diff options
author | Adam Edwards <adamed@opscode.com> | 2015-12-05 19:48:07 -0800 |
---|---|---|
committer | Adam Edwards <adamed@opscode.com> | 2015-12-05 19:48:07 -0800 |
commit | 8f420ee227e9e52255910b9772caa5ec86685285 (patch) | |
tree | f2c62d02a37e41be97594758506a3bddaca639c8 | |
parent | 0e78d8a39dc6c93e2b853c63c1ca4f3a273243f3 (diff) | |
download | chef-8f420ee227e9e52255910b9772caa5ec86685285.tar.gz |
Unit test for resource_credential mixinadamedx/alternate-user
-rw-r--r-- | lib/chef/mixin/resource_credential.rb | 36 | ||||
-rw-r--r-- | lib/chef/provider/remote_file/network_file.rb | 2 | ||||
-rw-r--r-- | spec/unit/mixin/resource_credential_spec.rb | 201 | ||||
-rw-r--r-- | spec/unit/provider/execute_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/provider/remote_file/network_file_spec.rb | 4 |
5 files changed, 229 insertions, 16 deletions
diff --git a/lib/chef/mixin/resource_credential.rb b/lib/chef/mixin/resource_credential.rb index f2c2d6d7fa..c3844f82b4 100644 --- a/lib/chef/mixin/resource_credential.rb +++ b/lib/chef/mixin/resource_credential.rb @@ -21,30 +21,38 @@ class Chef module ResourceCredential def validate_credential(specified_user, specified_domain, password) - user = specified_user - domain = specified_domain + validate_credential_platform(specified_user, specified_domain, password) + validate_credential_syntax(specified_user, specified_domain, password) + end - if Chef::Platform.windows? - if ! user.nil? - domain, user = canonicalize_credential(specified_domain, specified_user) + def validate_credential_platform(specified_user, specified_domain, password) + if ! Chef::Platform.windows? + if ! password.nil? || ! specified_domain.nil? + raise Exceptions::UnsupportedPlatform, "The `domain` and `password` properties are only supported on the Windows platform" end - - if ! user.nil? && password.nil? - raise ArgumentError, "No `password` property was specified when the `user` property was specified" + else + if ! specified_user.nil? && password.nil? + raise ArgumentError, "A `password` property must be specified when the `user` property is specified on the Windows platform" end - elsif ! domain.nil? || ! password.nil? - raise Exceptions::UnsupportedPlatform, "The `domain` and `password` properties are only supported on the Windows platform" end + end + + def validate_credential_syntax(specified_user, specified_domain, password) + domain, user = qualify_credential_user(specified_domain, specified_user) if ( ! password.nil? || ! domain.nil? ) && user.nil? raise ArgumentError, "The `password` or `domain` property was specified without specification of the user property" end end - def canonicalize_credential(specified_domain, specified_user) + def qualify_credential_user(specified_domain, specified_user) domain = specified_domain user = specified_user + if specified_user.nil? && ! specified_domain.nil? + raise ArgumentError, "The domain #{specified_domain} was specified, but no user name was given" + end + if ! specified_user.nil? && specified_domain.nil? domain_and_user = user.split('\\') @@ -63,8 +71,10 @@ class Chef [domain, user] end - private(:validate_credential) - private(:canonicalize_credential) + protected(:validate_credential) + protected(:validate_credential_platform) + protected(:validate_credential_syntax) + protected(:qualify_credential_user) end end diff --git a/lib/chef/provider/remote_file/network_file.rb b/lib/chef/provider/remote_file/network_file.rb index 7f837cc4cc..848fb41541 100644 --- a/lib/chef/provider/remote_file/network_file.rb +++ b/lib/chef/provider/remote_file/network_file.rb @@ -45,7 +45,7 @@ class Chef tempfile = Chef::FileContentManagement::Tempfile.new(new_resource).tempfile Chef::Log.debug("#{new_resource} staging #{@source} to #{tempfile.path}") - domain, user = canonicalize_credential( new_resource.remote_user_domain, new_resource.remote_user ) + domain, user = qualify_credential_user( new_resource.remote_user_domain, new_resource.remote_user ) with_user_context(user, domain, new_resource.remote_user_password) do ::File.open(@source, 'rb') do | remote_file | diff --git a/spec/unit/mixin/resource_credential_spec.rb b/spec/unit/mixin/resource_credential_spec.rb new file mode 100644 index 0000000000..8fa04c7494 --- /dev/null +++ b/spec/unit/mixin/resource_credential_spec.rb @@ -0,0 +1,201 @@ +#
+# Author:: Adam Edwards (<adamed@chef.io>)
+# Copyright:: Copyright (c) 2015 Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+require 'chef/mixin/resource_credential'
+
+shared_examples_for "it received valid credentials" do
+ describe "the validation method" do
+ it "should not raise an error" do
+ expect {instance_with_credential.validate(username, domain, password)}.not_to raise_error
+ end
+ end
+
+ describe "the name qualification method" do
+ it "should correctly translate the user and domain" do
+ qualified_user = nil
+ expect { qualified_user = instance_with_credential.qualify_name(domain, username)}.not_to raise_error
+ expect(qualified_user[0]).to eq(domain)
+ expect(qualified_user[1]).to eq(username)
+ end
+ end
+end
+
+shared_examples_for "it received invalid credentials" do
+ describe "the validation method" do
+ it "should raise an error" do
+ expect { instance_with_credential.validate(username, domain, password)}.to raise_error(ArgumentError)
+ end
+ end
+end
+
+shared_examples_for "it received credentials that are not valid on the platform" do
+ describe "the validation method" do
+ it "should raise an error" do
+ expect { instance_with_credential.validate(username, domain, password)}.to raise_error(Chef::Exceptions::UnsupportedPlatform)
+ end
+ end
+end
+
+shared_examples_for "a consumer of the resource_credential mixin" do
+ context "when running on Windows" do
+ before do
+ allow(::Chef::Platform).to receive(:windows?).and_return(true)
+ end
+
+ context "when no user, domain, or password is specified" do
+ let(:username) { nil }
+ let(:domain) { nil }
+ let(:password) { nil }
+ it_behaves_like "it received valid credentials"
+ end
+
+ context "when a valid username is specified" do
+ let(:username) { 'starchild' }
+ context "when a valid domain is specified" do
+ let(:domain) { 'mothership' }
+
+ context "when the password is not specified" do
+ let(:password) { nil }
+ it_behaves_like "it received invalid credentials"
+ end
+
+ context "when the password is specified" do
+ let(:password) { 'we.funk!' }
+ it_behaves_like "it received valid credentials"
+ end
+ end
+
+ context "when the domain is not specified" do
+ let(:domain) { nil }
+
+ context "when the password is not specified" do
+ let(:password) { nil }
+ it_behaves_like "it received invalid credentials"
+ end
+
+ context "when the password is specified" do
+ let(:password) { 'we.funk!' }
+ it_behaves_like "it received valid credentials"
+ end
+ end
+ end
+
+ context "when the username is not specified" do
+ let(:username) { nil }
+
+ context "when the password is specified and the domain is not" do
+ let(:password) { 'we.funk!' }
+ let(:domain) { nil }
+ it_behaves_like "it received invalid credentials"
+ end
+
+ context "when the domain is specified and the password is not" do
+ let(:domain) { 'mothership' }
+ let(:password) { nil }
+ it_behaves_like "it received invalid credentials"
+ end
+
+ context "when the domain and password are specified" do
+ let(:domain) { 'mothership' }
+ let(:password) { 'we.funk!' }
+ it_behaves_like "it received invalid credentials"
+ end
+ end
+ end
+
+ context "when not running on Windows" do
+ before do
+ allow(::Chef::Platform).to receive(:windows?).and_return(false)
+ end
+
+ context "when no user, domain, or password is specified" do
+ let(:username) { nil }
+ let(:domain) { nil }
+ let(:password) { nil }
+ it_behaves_like "it received valid credentials"
+ end
+
+ context "when the user is specified and the domain and password are not" do
+ let(:username) { 'starchild' }
+ let(:domain) { nil }
+ let(:password) { nil }
+ it_behaves_like "it received valid credentials"
+
+ context "when the password is specified and the domain is not" do
+ let(:password) { 'we.funk!' }
+ let(:domain) { nil }
+ it_behaves_like "it received credentials that are not valid on the platform"
+ end
+
+ context "when the domain is specified and the password is not" do
+ let(:domain) { 'mothership' }
+ let(:password) { nil }
+ it_behaves_like "it received credentials that are not valid on the platform"
+ end
+
+ context "when the domain and password are specified" do
+ let(:domain) { 'mothership' }
+ let(:password) { 'we.funk!' }
+ it_behaves_like "it received credentials that are not valid on the platform"
+ end
+ end
+
+ context "when the user is not specified" do
+ let(:username) { nil }
+ context "when the domain is specified" do
+ let(:domain) { 'mothership' }
+ context "when the password is specified" do
+ let(:password) { 'we.funk!' }
+ it_behaves_like "it received credentials that are not valid on the platform"
+ end
+
+ context "when password is not specified" do
+ let(:password) { nil }
+ it_behaves_like "it received credentials that are not valid on the platform"
+ end
+ end
+
+ context "when the domain is not specified" do
+ let(:domain) { nil }
+ context "when the password is specified" do
+ let(:password) { 'we.funk!' }
+ it_behaves_like "it received credentials that are not valid on the platform"
+ end
+ end
+ end
+ end
+end
+
+describe "a class that mixes in resource_credential" do
+ let(:instance_with_credential) do
+ class CredentialClass
+ include ::Chef::Mixin::ResourceCredential
+ def validate(*args)
+ validate_credential(*args)
+ end
+
+ def qualify_name(*args)
+ qualify_credential_user(*args)
+ end
+ end
+ CredentialClass.new
+ end
+
+ it_behaves_like "a consumer of the resource_credential mixin"
+end
diff --git a/spec/unit/provider/execute_spec.rb b/spec/unit/provider/execute_spec.rb index 3d171dfed1..cbcb9373c4 100644 --- a/spec/unit/provider/execute_spec.rb +++ b/spec/unit/provider/execute_spec.rb @@ -237,7 +237,7 @@ describe Chef::Provider::Execute do expect { provider.run_action(:run) }.to raise_error(ArgumentError) end - it "should raise an error if the domain and user are specified" do + it "should raise an error if the domain and password are specified" do expect(new_resource).to receive(:password).at_least(1).times.and_return('we.funk!') expect(new_resource).to receive(:domain).at_least(1).times.and_return('mothership') expect { provider.run_action(:run) }.to raise_error(ArgumentError) diff --git a/spec/unit/provider/remote_file/network_file_spec.rb b/spec/unit/provider/remote_file/network_file_spec.rb index 3666a47468..c39b6d0951 100644 --- a/spec/unit/provider/remote_file/network_file_spec.rb +++ b/spec/unit/provider/remote_file/network_file_spec.rb @@ -1,3 +1,4 @@ + # # Author:: Jay Mundrawala (<jdm@chef.io>) # Copyright:: Copyright (c) 2015 Chef Software @@ -30,10 +31,11 @@ describe Chef::Provider::RemoteFile::NetworkFile do let(:tempfile) { double("Tempfile", :path => "/tmp/foo/bar/Foo.tar.gz", :close => nil) } let(:chef_tempfile) { double("Chef::FileContentManagement::Tempfile", :tempfile => tempfile) } + let(:source_file) { double("::File", :read => nil) } it "stages the local file to a temporary file" do expect(Chef::FileContentManagement::Tempfile).to receive(:new).with(new_resource).and_return(chef_tempfile) - expect(::FileUtils).to receive(:cp).with(source, tempfile.path) + expect(::File).to receive(:open).with(source, 'rb').and_return(source_file) expect(tempfile).to receive(:close) result = fetcher.fetch |