summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorJay Mundrawala <jdmundrawala@gmail.com>2015-03-24 10:21:14 -0700
committerJay Mundrawala <jdmundrawala@gmail.com>2015-03-24 10:21:14 -0700
commitd3e4e565fdf7c210acfd8efd0de6b674883a5e0f (patch)
tree5fd2f1b237e39c81d8a7b54e0cdc0279e7528435 /spec
parent17014504259f8ccb19d782bd3b63b24657e4c9ca (diff)
parent157852156703daf96366dd773903147baf0292d9 (diff)
downloadchef-7296c5ece82c77334c7fce2787f267b79c4e8736.tar.gz
Merge pull request #3128 from chef/jdm/prepare-12.2.012.2.0.rc.0
prepare 12.2.0 RC 0
Diffstat (limited to 'spec')
-rw-r--r--spec/functional/file_content_management/deploy_strategies_spec.rb2
-rw-r--r--spec/functional/resource/cookbook_file_spec.rb2
-rw-r--r--spec/functional/resource/deploy_revision_spec.rb35
-rw-r--r--spec/functional/resource/directory_spec.rb2
-rw-r--r--spec/functional/resource/dsc_resource_spec.rb93
-rwxr-xr-xspec/functional/resource/env_spec.rb7
-rw-r--r--spec/functional/resource/file_spec.rb2
-rw-r--r--spec/functional/resource/powershell_spec.rb3
-rw-r--r--spec/functional/resource/remote_directory_spec.rb2
-rw-r--r--spec/functional/resource/remote_file_spec.rb2
-rw-r--r--spec/functional/resource/template_spec.rb2
-rw-r--r--spec/functional/resource/user/dscl_spec.rb3
-rw-r--r--spec/functional/resource/user/useradd_spec.rb40
-rw-r--r--spec/functional/win32/crypto_spec.rb57
-rw-r--r--spec/spec_helper.rb3
-rw-r--r--spec/support/platform_helpers.rb14
-rw-r--r--spec/support/shared/functional/securable_resource_with_reporting.rb10
-rw-r--r--spec/unit/application/client_spec.rb8
-rw-r--r--spec/unit/audit/audit_reporter_spec.rb2
-rw-r--r--spec/unit/audit/runner_spec.rb10
-rw-r--r--spec/unit/config_spec.rb10
-rw-r--r--spec/unit/knife/bootstrap_spec.rb28
-rw-r--r--spec/unit/knife/core/subcommand_loader_spec.rb58
-rw-r--r--spec/unit/mixin/params_validate_spec.rb136
-rw-r--r--spec/unit/mixin/powershell_type_coercions_spec.rb72
-rw-r--r--spec/unit/platform/query_helpers_spec.rb22
-rw-r--r--spec/unit/platform_spec.rb5
-rw-r--r--spec/unit/provider/dsc_resource_spec.rb84
-rw-r--r--spec/unit/provider/package/openbsd_spec.rb122
-rw-r--r--spec/unit/provider/service/macosx_spec.rb6
-rw-r--r--spec/unit/provider_resolver_spec.rb132
-rw-r--r--spec/unit/recipe_spec.rb4
-rw-r--r--spec/unit/resource/deploy_spec.rb27
-rw-r--r--spec/unit/resource/dsc_resource_spec.rb85
-rw-r--r--spec/unit/shell_spec.rb2
-rw-r--r--spec/unit/util/dsc/resource_store.rb76
-rw-r--r--spec/unit/util/powershell/ps_credential_spec.rb37
-rw-r--r--spec/unit/workstation_config_loader_spec.rb2
38 files changed, 1038 insertions, 169 deletions
diff --git a/spec/functional/file_content_management/deploy_strategies_spec.rb b/spec/functional/file_content_management/deploy_strategies_spec.rb
index 03a6c504c1..8a995d0e41 100644
--- a/spec/functional/file_content_management/deploy_strategies_spec.rb
+++ b/spec/functional/file_content_management/deploy_strategies_spec.rb
@@ -43,7 +43,7 @@ shared_examples_for "a content deploy strategy" do
##
# UNIX Context
- let(:default_mode) { normalize_mode(0100666 - File.umask) }
+ let(:default_mode) { normalize_mode(0666 & ~File.umask) }
it "touches the file to create it (UNIX)", :unix_only do
content_deployer.create(target_file_path)
diff --git a/spec/functional/resource/cookbook_file_spec.rb b/spec/functional/resource/cookbook_file_spec.rb
index 7797ed0041..6d4c5b4a8f 100644
--- a/spec/functional/resource/cookbook_file_spec.rb
+++ b/spec/functional/resource/cookbook_file_spec.rb
@@ -32,7 +32,7 @@ describe Chef::Resource::CookbookFile do
content
end
- let(:default_mode) { ((0100666 - File.umask) & 07777).to_s(8) }
+ let(:default_mode) { (0666 & ~File.umask).to_s(8) }
it_behaves_like "a securable resource with reporting"
diff --git a/spec/functional/resource/deploy_revision_spec.rb b/spec/functional/resource/deploy_revision_spec.rb
index e5f5341fcd..bd45e32771 100644
--- a/spec/functional/resource/deploy_revision_spec.rb
+++ b/spec/functional/resource/deploy_revision_spec.rb
@@ -201,6 +201,41 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
end
end
+ describe "setting default parameters to nil" do
+ before do
+ FileUtils.mkdir_p(rel_path("releases"))
+ FileUtils.mkdir_p(rel_path("shared"))
+ end
+
+ it "supports setting symlink_before_migrate to nil" do
+ deploy_to_latest_rev.symlink_before_migrate(nil)
+ expect(deploy_to_latest_rev.symlink_before_migrate).to eql(nil)
+ deploy_to_latest_rev.run_action(:deploy)
+ expect(deploy_to_latest_rev).to be_updated_by_last_action
+ end
+
+ it "supports setting symlinks to nil" do
+ deploy_to_latest_rev.symlinks(nil)
+ expect(deploy_to_latest_rev.symlinks).to eql(nil)
+ deploy_to_latest_rev.run_action(:deploy)
+ expect(deploy_to_latest_rev).to be_updated_by_last_action
+ end
+
+ it "supports setting purge_before_symlink to nil" do
+ deploy_to_latest_rev.purge_before_symlink(nil)
+ expect(deploy_to_latest_rev.purge_before_symlink).to eql(nil)
+ deploy_to_latest_rev.run_action(:deploy)
+ expect(deploy_to_latest_rev).to be_updated_by_last_action
+ end
+
+ it "supports setting create_dirs_before_symlink to nil" do
+ deploy_to_latest_rev.create_dirs_before_symlink(nil)
+ expect(deploy_to_latest_rev.create_dirs_before_symlink).to eql(nil)
+ deploy_to_latest_rev.run_action(:deploy)
+ expect(deploy_to_latest_rev).to be_updated_by_last_action
+ end
+ end
+
describe "back to a previously deployed revision, with the directory structure precreated" do
before do
FileUtils.mkdir_p(rel_path("releases"))
diff --git a/spec/functional/resource/directory_spec.rb b/spec/functional/resource/directory_spec.rb
index 2c4025f83e..88a810964f 100644
--- a/spec/functional/resource/directory_spec.rb
+++ b/spec/functional/resource/directory_spec.rb
@@ -23,7 +23,7 @@ describe Chef::Resource::Directory do
let(:directory_base) { "directory_spec" }
- let(:default_mode) { ((0100777 - File.umask) & 07777).to_s(8) }
+ let(:default_mode) { (0777 & ~File.umask).to_s(8) }
def create_resource
events = Chef::EventDispatch::Dispatcher.new
diff --git a/spec/functional/resource/dsc_resource_spec.rb b/spec/functional/resource/dsc_resource_spec.rb
new file mode 100644
index 0000000000..6f453eeb9f
--- /dev/null
+++ b/spec/functional/resource/dsc_resource_spec.rb
@@ -0,0 +1,93 @@
+#
+# Author:: Jay Mundrawala (<jdm@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'
+
+describe Chef::Resource::DscResource, :windows_powershell_dsc_only do
+ before(:all) do
+ @ohai = Ohai::System.new
+ @ohai.all_plugins(['platform', 'os', 'languages/powershell'])
+ end
+
+ let(:event_dispatch) { Chef::EventDispatch::Dispatcher.new }
+
+ let(:node) {
+ Chef::Node.new.tap do |n|
+ n.consume_external_attrs(@ohai.data, {})
+ end
+ }
+
+ let(:run_context) { Chef::RunContext.new(node, {}, event_dispatch) }
+
+ let(:new_resource) {
+ Chef::Resource::DscResource.new("dsc_resource_test", run_context)
+ }
+
+ context 'when Powershell does not support Invoke-DscResource'
+ context 'when Powershell supports Invoke-DscResource' do
+ before do
+ if !Chef::Platform.supports_dsc_invoke_resource?(node)
+ skip 'Requires Powershell >= 5.0.10018.0'
+ end
+ end
+ context 'with an invalid dsc resource' do
+ it 'raises an exception if the resource is not found' do
+ new_resource.resource 'thisdoesnotexist'
+ expect { new_resource.run_action(:run) }.to raise_error(
+ Chef::Exceptions::ResourceNotFound)
+ end
+ end
+
+ context 'with a valid dsc resource' do
+ let(:tmp_file_name) { Dir::Tmpname.create('tmpfile') {} }
+ let(:test_text) { "'\"!@#$%^&*)(}{][\u2713~n"}
+
+ before do
+ new_resource.resource :File
+ new_resource.property :Contents, test_text
+ new_resource.property :DestinationPath, tmp_file_name
+ end
+
+ after do
+ File.delete(tmp_file_name) if File.exists? tmp_file_name
+ end
+
+ it 'converges the resource if it is not converged' do
+ new_resource.run_action(:run)
+ contents = File.open(tmp_file_name, 'rb:bom|UTF-16LE') do |f|
+ f.read.encode('UTF-8')
+ end
+ expect(contents).to eq(test_text)
+ expect(new_resource).to be_updated
+ end
+
+ it 'does not converge the resource if it is already converged' do
+ new_resource.run_action(:run)
+ expect(new_resource).to be_updated
+ reresource =
+ Chef::Resource::DscResource.new("dsc_resource_retest", run_context)
+ reresource.resource :File
+ reresource.property :Contents, test_text
+ reresource.property :DestinationPath, tmp_file_name
+ reresource.run_action(:run)
+ expect(reresource).not_to be_updated
+ end
+ end
+
+ end
+end
diff --git a/spec/functional/resource/env_spec.rb b/spec/functional/resource/env_spec.rb
index 16caec14bf..b9dcd7b33a 100755
--- a/spec/functional/resource/env_spec.rb
+++ b/spec/functional/resource/env_spec.rb
@@ -29,14 +29,15 @@ describe Chef::Resource::Env, :windows_only do
let(:env_value_expandable) { '%SystemRoot%' }
let(:test_run_context) {
node = Chef::Node.new
+ node.default['os'] = 'windows'
node.default['platform'] = 'windows'
node.default['platform_version'] = '6.1'
empty_events = Chef::EventDispatch::Dispatcher.new
Chef::RunContext.new(node, {}, empty_events)
}
- let(:test_resource) {
- Chef::Resource::Env.new('unknown', test_run_context)
- }
+ let(:test_resource) {
+ Chef::Resource::Env.new('unknown', test_run_context)
+ }
before(:each) do
resource_lower = Chef::Resource::Env.new(chef_env_test_lower_case, test_run_context)
diff --git a/spec/functional/resource/file_spec.rb b/spec/functional/resource/file_spec.rb
index cf70c349fb..f1a290dea4 100644
--- a/spec/functional/resource/file_spec.rb
+++ b/spec/functional/resource/file_spec.rb
@@ -64,7 +64,7 @@ describe Chef::Resource::File do
provider.current_resource
end
- let(:default_mode) { ((0100666 - File.umask) & 07777).to_s(8) }
+ let(:default_mode) { (0666 & ~File.umask).to_s(8) }
it_behaves_like "a file resource"
diff --git a/spec/functional/resource/powershell_spec.rb b/spec/functional/resource/powershell_spec.rb
index 1b3ac844e0..56a905efe7 100644
--- a/spec/functional/resource/powershell_spec.rb
+++ b/spec/functional/resource/powershell_spec.rb
@@ -56,7 +56,8 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
resource.run_action(:run)
end
- it "returns the -27 for a powershell script that exits with -27" do
+ it "returns the -27 for a powershell script that exits with -27", :windows_powershell_dsc_only do
+ # This is broken on Powershell < 4.0
file = Tempfile.new(['foo', '.ps1'])
begin
file.write "exit -27"
diff --git a/spec/functional/resource/remote_directory_spec.rb b/spec/functional/resource/remote_directory_spec.rb
index bcafca7399..37ffbbc971 100644
--- a/spec/functional/resource/remote_directory_spec.rb
+++ b/spec/functional/resource/remote_directory_spec.rb
@@ -22,7 +22,7 @@ describe Chef::Resource::RemoteDirectory do
include_context Chef::Resource::Directory
let(:directory_base) { "directory_spec" }
- let(:default_mode) { ((0100777 - File.umask) & 07777).to_s(8) }
+ let(:default_mode) { (0777 & ~File.umask).to_s(8) }
def create_resource
cookbook_repo = File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks"))
diff --git a/spec/functional/resource/remote_file_spec.rb b/spec/functional/resource/remote_file_spec.rb
index 29091fd785..4fbcd2d24b 100644
--- a/spec/functional/resource/remote_file_spec.rb
+++ b/spec/functional/resource/remote_file_spec.rb
@@ -52,7 +52,7 @@ describe Chef::Resource::RemoteFile do
create_resource
end
- let(:default_mode) { ((0100666 - File.umask) & 07777).to_s(8) }
+ let(:default_mode) { (0666 & ~File.umask).to_s(8) }
context "when fetching files over HTTP" do
before(:all) do
diff --git a/spec/functional/resource/template_spec.rb b/spec/functional/resource/template_spec.rb
index d7b35e7450..35c5166e31 100644
--- a/spec/functional/resource/template_spec.rb
+++ b/spec/functional/resource/template_spec.rb
@@ -58,7 +58,7 @@ describe Chef::Resource::Template do
create_resource
end
- let(:default_mode) { ((0100666 - File.umask) & 07777).to_s(8) }
+ let(:default_mode) { (0666 & ~File.umask).to_s(8) }
it_behaves_like "a file resource"
diff --git a/spec/functional/resource/user/dscl_spec.rb b/spec/functional/resource/user/dscl_spec.rb
index 45b6754453..5d960daf11 100644
--- a/spec/functional/resource/user/dscl_spec.rb
+++ b/spec/functional/resource/user/dscl_spec.rb
@@ -19,9 +19,8 @@ require 'spec_helper'
require 'chef/mixin/shell_out'
metadata = {
- :unix_only => true,
+ :mac_osx_only => true,
:requires_root => true,
- :provider => {:user => Chef::Provider::User::Dscl},
:not_supported_on_mac_osx_106 => true,
}
diff --git a/spec/functional/resource/user/useradd_spec.rb b/spec/functional/resource/user/useradd_spec.rb
index 9ac88d7b60..3e4e4e7604 100644
--- a/spec/functional/resource/user/useradd_spec.rb
+++ b/spec/functional/resource/user/useradd_spec.rb
@@ -32,6 +32,7 @@ end
metadata = { :unix_only => true,
:requires_root => true,
+ :not_supported_on_mac_osx => true,
:provider => {:user => user_provider_for_platform}
}
@@ -76,9 +77,22 @@ describe Chef::Provider::User::Useradd, metadata do
end
end
+ def try_cleanup
+ ['/home/cheftestfoo', '/home/cheftestbar'].each do |f|
+ FileUtils.rm_rf(f) if File.exists? f
+ end
+
+ ['cf-test'].each do |u|
+ r = Chef::Resource::User.new("DELETE USER", run_context)
+ r.username('cf-test')
+ r.run_action(:remove)
+ end
+ end
+
before do
# Silence shell_out live stream
Chef::Log.level = :warn
+ try_cleanup
end
after do
@@ -386,18 +400,18 @@ describe Chef::Provider::User::Useradd, metadata do
end
context "and home directory is updated" do
- let(:existing_home) { "/home/foo" }
- let(:home) { "/home/bar" }
+ let(:existing_home) { "/home/cheftestfoo" }
+ let(:home) { "/home/cheftestbar" }
it "ensures the home directory is set to the desired value" do
- expect(pw_entry.home).to eq("/home/bar")
+ expect(pw_entry.home).to eq("/home/cheftestbar")
end
context "and manage_home is enabled" do
let(:existing_manage_home) { true }
let(:manage_home) { true }
it "moves the home directory to the new location" do
- expect(File).not_to exist("/home/foo")
- expect(File).to exist("/home/bar")
+ expect(File).not_to exist("/home/cheftestfoo")
+ expect(File).to exist("/home/cheftestbar")
end
end
@@ -409,19 +423,19 @@ describe Chef::Provider::User::Useradd, metadata do
# Inconsistent behavior. See: CHEF-2205
it "created the home dir b/c of CHEF-2205 so it still exists" do
# This behavior seems contrary to expectation and non-convergent.
- expect(File).not_to exist("/home/foo")
- expect(File).to exist("/home/bar")
+ expect(File).not_to exist("/home/cheftestfoo")
+ expect(File).to exist("/home/cheftestbar")
end
elsif ohai[:platform] == "aix"
it "creates the home dir in the desired location" do
- expect(File).not_to exist("/home/foo")
- expect(File).to exist("/home/bar")
+ expect(File).not_to exist("/home/cheftestfoo")
+ expect(File).to exist("/home/cheftestbar")
end
else
it "does not create the home dir in the desired location (XXX)" do
# This behavior seems contrary to expectation and non-convergent.
- expect(File).not_to exist("/home/foo")
- expect(File).not_to exist("/home/bar")
+ expect(File).not_to exist("/home/cheftestfoo")
+ expect(File).not_to exist("/home/cheftestbar")
end
end
end
@@ -432,8 +446,8 @@ describe Chef::Provider::User::Useradd, metadata do
it "leaves the old home directory around (XXX)" do
# Would it be better to remove the old home?
- expect(File).to exist("/home/foo")
- expect(File).not_to exist("/home/bar")
+ expect(File).to exist("/home/cheftestfoo")
+ expect(File).not_to exist("/home/cheftestbar")
end
end
end
diff --git a/spec/functional/win32/crypto_spec.rb b/spec/functional/win32/crypto_spec.rb
new file mode 100644
index 0000000000..1492995886
--- /dev/null
+++ b/spec/functional/win32/crypto_spec.rb
@@ -0,0 +1,57 @@
+#
+# Author:: Jay Mundrawala(<jdm@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'
+if Chef::Platform.windows?
+ require 'chef/win32/crypto'
+end
+
+describe 'Chef::ReservedNames::Win32::Crypto', :windows_only do
+ describe '#encrypt' do
+ before(:all) do
+ ohai_reader = Ohai::System.new
+ ohai_reader.all_plugins("platform")
+
+ new_node = Chef::Node.new
+ new_node.consume_external_attrs(ohai_reader.data,{})
+
+ events = Chef::EventDispatch::Dispatcher.new
+
+ @run_context = Chef::RunContext.new(new_node, {}, events)
+ end
+
+ let (:plaintext) { 'p@assword' }
+
+ it 'can be decrypted by powershell' do
+ encrypted = Chef::ReservedNames::Win32::Crypto.encrypt(plaintext)
+ resource = Chef::Resource::WindowsScript::PowershellScript.new("Powershell resource functional test", @run_context)
+ resource.code <<-EOF
+$encrypted = '#{encrypted}' | ConvertTo-SecureString
+$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($encrypted)
+$plaintext = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
+if ($plaintext -ne '#{plaintext}') {
+ Write-Error 'Got: ' $plaintext
+ exit 1
+}
+exit 0
+ EOF
+ resource.returns(0)
+ resource.run_action(:run)
+ end
+ end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 8888efc424..fb284c721b 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -110,10 +110,13 @@ RSpec.configure do |config|
# Tests that randomly fail, but may have value.
config.filter_run_excluding :volatile => true
config.filter_run_excluding :volatile_on_solaris => true if solaris?
+ config.filter_run_excluding :volatile_from_verify => false
# Add jruby filters here
config.filter_run_excluding :windows_only => true unless windows?
config.filter_run_excluding :not_supported_on_mac_osx_106 => true if mac_osx_106?
+ config.filter_run_excluding :not_supported_on_mac_osx=> true if mac_osx?
+ config.filter_run_excluding :mac_osx_only=> true if !mac_osx?
config.filter_run_excluding :not_supported_on_win2k3 => true if windows_win2k3?
config.filter_run_excluding :not_supported_on_solaris => true if solaris?
config.filter_run_excluding :win2k3_only => true unless windows_win2k3?
diff --git a/spec/support/platform_helpers.rb b/spec/support/platform_helpers.rb
index a412fe38e1..da0313758b 100644
--- a/spec/support/platform_helpers.rb
+++ b/spec/support/platform_helpers.rb
@@ -88,6 +88,20 @@ def mac_osx_106?
false
end
+def mac_osx?
+ if File.exists? "/usr/bin/sw_vers"
+ result = ShellHelpers.shell_out("/usr/bin/sw_vers")
+ result.stdout.each_line do |line|
+ if line =~ /^ProductName:\sMac OS X.*$/
+ return true
+ end
+ end
+ end
+
+ false
+end
+
+
# detects if the hardware is 64-bit (evaluates to true in "WOW64" mode in a 32-bit app on a 64-bit system)
def windows64?
windows? && ( ENV['PROCESSOR_ARCHITECTURE'] == 'AMD64' || ENV['PROCESSOR_ARCHITEW6432'] == 'AMD64' )
diff --git a/spec/support/shared/functional/securable_resource_with_reporting.rb b/spec/support/shared/functional/securable_resource_with_reporting.rb
index 8a2ceed837..37fc538801 100644
--- a/spec/support/shared/functional/securable_resource_with_reporting.rb
+++ b/spec/support/shared/functional/securable_resource_with_reporting.rb
@@ -35,7 +35,7 @@ shared_examples_for "a securable resource with reporting" do
# Default mode varies based on implementation. Providers that use a tempfile
# will default to 0600. Providers that use File.open will default to 0666 -
# umask
- # let(:default_mode) { ((0100666 - File.umask) & 07777).to_s(8) }
+ # let(:default_mode) { (0666 & ~File.umask).to_s(8) }
describe "reading file security metadata for reporting on unix", :unix_only => true do
# According to POSIX standard created files get either the
@@ -185,7 +185,7 @@ shared_examples_for "a securable resource with reporting" do
# TODO: most stable way to specify?
expect(current_resource.owner).to eq(Etc.getpwuid(Process.uid).name)
expect(current_resource.group).to eq(@expected_group_name)
- expect(current_resource.mode).to eq("0#{((0100666 - File.umask) & 07777).to_s(8)}")
+ expect(current_resource.mode).to eq("0#{(0666 & ~File.umask).to_s(8)}")
end
end
@@ -239,8 +239,8 @@ shared_examples_for "a securable resource with reporting" do
end
context "and mode is specified as a String" do
- let(:default_create_mode) { (0100666 - File.umask) }
- let(:expected_mode) { "0#{(default_create_mode & 07777).to_s(8)}" }
+ let(:default_create_mode) { 0666 & ~File.umask }
+ let(:expected_mode) { "0#{default_create_mode.to_s(8)}" }
before do
resource.mode(expected_mode)
@@ -252,7 +252,7 @@ shared_examples_for "a securable resource with reporting" do
end
context "and mode is specified as an Integer" do
- let(:set_mode) { (0100666 - File.umask) & 07777 }
+ let(:set_mode) { 0666 & ~File.umask }
let(:expected_mode) { "0#{set_mode.to_s(8)}" }
before do
diff --git a/spec/unit/application/client_spec.rb b/spec/unit/application/client_spec.rb
index ea2ad473e5..501251b7fe 100644
--- a/spec/unit/application/client_spec.rb
+++ b/spec/unit/application/client_spec.rb
@@ -305,7 +305,7 @@ describe Chef::Application::Client, "run_application", :unix_only do
allow(Chef::Daemon).to receive(:daemonize).and_return(true)
end
- it "should exit hard with exitstatus 3" do
+ it "should exit hard with exitstatus 3", :volatile do
pid = fork do
@app.run_application
end
@@ -320,9 +320,9 @@ describe Chef::Application::Client, "run_application", :unix_only do
end
expect(@pipe[0].gets).to eq("started\n")
Process.kill("TERM", pid)
- Process.wait
- sleep 1 # Make sure we give the converging child process enough time to finish
- expect(IO.select([@pipe[0]], nil, nil, 0)).not_to be_nil
+ Process.wait(pid)
+ # The timeout value needs to be large enough for the child process to finish
+ expect(IO.select([@pipe[0]], nil, nil, 15)).not_to be_nil
expect(@pipe[0].gets).to eq("finished\n")
end
end
diff --git a/spec/unit/audit/audit_reporter_spec.rb b/spec/unit/audit/audit_reporter_spec.rb
index 84d7ea82f0..4bf889510a 100644
--- a/spec/unit/audit/audit_reporter_spec.rb
+++ b/spec/unit/audit/audit_reporter_spec.rb
@@ -203,7 +203,7 @@ describe Chef::Audit::AuditReporter do
it "doesn't send reports" do
expect(reporter).to receive(:auditing_enabled?).and_return(true)
expect(reporter).to receive(:run_status).and_return(nil)
- expect(Chef::Log).to receive(:debug).with("Run failed before audits were initialized, not sending audit report to server")
+ expect(Chef::Log).to receive(:debug).with("Run failed before audit mode was initialized, not sending audit report to server")
reporter.run_completed(node)
end
diff --git a/spec/unit/audit/runner_spec.rb b/spec/unit/audit/runner_spec.rb
index 801147bdb9..0bd4c18388 100644
--- a/spec/unit/audit/runner_spec.rb
+++ b/spec/unit/audit/runner_spec.rb
@@ -36,6 +36,15 @@ describe Chef::Audit::Runner do
RSpec::Core::Sandbox.sandboxed { ex.run }
end
+ context "when we run in audit mode" do
+ let(:paths) { [ "/opt/chef/lib/chef/", 'C:\windows/here/lib/chef/' , "/opt/chef/extra/folders/lib/chef/"] }
+ it "excludes the current path from backtrace" do
+ paths.each do |path|
+ expect(runner.exclusion_pattern).to match(path)
+ end
+ end
+ end
+
describe "#initialize" do
it "correctly sets the run_context during initialization" do
expect(runner.instance_variable_get(:@run_context)).to eq(run_context)
@@ -72,6 +81,7 @@ describe Chef::Audit::Runner do
expect(RSpec.configuration.color).to eq(color)
expect(RSpec.configuration.expose_dsl_globally?).to eq(false)
+ expect(RSpec.configuration.backtrace_exclusion_patterns).to include(runner.exclusion_pattern)
expect(Specinfra.configuration.backend).to eq(:exec)
end
diff --git a/spec/unit/config_spec.rb b/spec/unit/config_spec.rb
index 06178f7733..6ea67246b5 100644
--- a/spec/unit/config_spec.rb
+++ b/spec/unit/config_spec.rb
@@ -360,18 +360,12 @@ describe Chef::Config do
describe "Chef::Config[:user_home]" do
it "should set when HOME is provided" do
expected = to_platform("/home/kitten")
- allow(Chef::Config).to receive(:env).and_return({ 'HOME' => expected })
- expect(Chef::Config[:user_home]).to eq(expected)
- end
-
- it "should be set when only USERPROFILE is provided" do
- expected = to_platform("/users/kitten")
- allow(Chef::Config).to receive(:env).and_return({ 'USERPROFILE' => expected })
+ allow(Chef::Util::PathHelper).to receive(:home).and_return(expected)
expect(Chef::Config[:user_home]).to eq(expected)
end
it "falls back to the current working directory when HOME and USERPROFILE is not set" do
- allow(Chef::Config).to receive(:env).and_return({})
+ allow(Chef::Util::PathHelper).to receive(:home).and_return(nil)
expect(Chef::Config[:user_home]).to eq(Dir.pwd)
end
end
diff --git a/spec/unit/knife/bootstrap_spec.rb b/spec/unit/knife/bootstrap_spec.rb
index 848af11db5..f1ca510ed3 100644
--- a/spec/unit/knife/bootstrap_spec.rb
+++ b/spec/unit/knife/bootstrap_spec.rb
@@ -115,7 +115,7 @@ describe Chef::Knife::Bootstrap do
end
def configure_env_home
- ENV['HOME'] = "/env/home"
+ allow(Chef::Util::PathHelper).to receive(:home).with(".chef", "bootstrap", "example.erb").and_yield(env_home_template_path)
end
def configure_gem_files
@@ -123,15 +123,9 @@ describe Chef::Knife::Bootstrap do
end
before(:each) do
- @original_home = ENV['HOME']
- ENV['HOME'] = nil
expect(File).to receive(:exists?).with(bootstrap_template).and_return(false)
end
- after(:each) do
- ENV['HOME'] = @original_home
- end
-
context "when file is available everywhere" do
before do
configure_chef_config_dir
@@ -161,7 +155,7 @@ describe Chef::Knife::Bootstrap do
end
end
- context "when file is available in ENV['HOME']" do
+ context "when file is available in home directory" do
before do
configure_chef_config_dir
configure_env_home
@@ -180,7 +174,25 @@ describe Chef::Knife::Bootstrap do
context "when file is available in Gem files" do
before do
configure_chef_config_dir
+ configure_env_home
+ configure_gem_files
+
+ expect(File).to receive(:exists?).with(builtin_template_path).and_return(false)
+ expect(File).to receive(:exists?).with(chef_config_dir_template_path).and_return(false)
+ expect(File).to receive(:exists?).with(env_home_template_path).and_return(false)
+ expect(File).to receive(:exists?).with(gem_files_template_path).and_return(true)
+ end
+
+ it "should load the template from Gem files" do
+ expect(knife.find_template).to eq(gem_files_template_path)
+ end
+ end
+
+ context "when file is available in Gem files and home dir doesn't exist" do
+ before do
+ configure_chef_config_dir
configure_gem_files
+ allow(Chef::Util::PathHelper).to receive(:home).with(".chef", "bootstrap", "example.erb").and_return(nil)
expect(File).to receive(:exists?).with(builtin_template_path).and_return(false)
expect(File).to receive(:exists?).with(chef_config_dir_template_path).and_return(false)
diff --git a/spec/unit/knife/core/subcommand_loader_spec.rb b/spec/unit/knife/core/subcommand_loader_spec.rb
index df42cff2ea..7f9308b28a 100644
--- a/spec/unit/knife/core/subcommand_loader_spec.rb
+++ b/spec/unit/knife/core/subcommand_loader_spec.rb
@@ -19,23 +19,29 @@
require 'spec_helper'
describe Chef::Knife::SubcommandLoader do
+ let(:loader) { Chef::Knife::SubcommandLoader.new(File.join(CHEF_SPEC_DATA, 'knife-site-subcommands')) }
+ let(:home) { File.join(CHEF_SPEC_DATA, 'knife-home') }
+ let(:plugin_dir) { File.join(home, '.chef', 'plugins', 'knife') }
+
before do
allow(Chef::Platform).to receive(:windows?) { false }
- @home = File.join(CHEF_SPEC_DATA, 'knife-home')
- @env = {'HOME' => @home}
- @loader = Chef::Knife::SubcommandLoader.new(File.join(CHEF_SPEC_DATA, 'knife-site-subcommands'), @env)
+ Chef::Util::PathHelper.class_variable_set(:@@home_dir, home)
+ end
+
+ after do
+ Chef::Util::PathHelper.class_variable_set(:@@home_dir, nil)
end
it "builds a list of the core subcommand file require paths" do
- expect(@loader.subcommand_files).not_to be_empty
- @loader.subcommand_files.each do |require_path|
+ expect(loader.subcommand_files).not_to be_empty
+ loader.subcommand_files.each do |require_path|
expect(require_path).to match(/chef\/knife\/.*|plugins\/knife\/.*/)
end
end
it "finds files installed via rubygems" do
- expect(@loader.find_subcommands_via_rubygems).to include('chef/knife/node_create')
- @loader.find_subcommands_via_rubygems.each {|rel_path, abs_path| expect(abs_path).to match(%r[chef/knife/.+])}
+ expect(loader.find_subcommands_via_rubygems).to include('chef/knife/node_create')
+ loader.find_subcommands_via_rubygems.each {|rel_path, abs_path| expect(abs_path).to match(%r[chef/knife/.+])}
end
it "finds files from latest version of installed gems" do
@@ -54,23 +60,23 @@ describe Chef::Knife::SubcommandLoader do
expect(gems[0]).to receive(:full_gem_path).and_return('/usr/lib/ruby/gems/knife-ec2-0.5.12')
expect(Dir).to receive(:[]).with('/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/*.rb').and_return(gem_files)
end
- expect(@loader).to receive(:find_subcommands_via_dirglob).and_return({})
- expect(@loader.find_subcommands_via_rubygems.values.select { |file| file =~ /knife-ec2/ }.sort).to eq(gem_files)
+ expect(loader).to receive(:find_subcommands_via_dirglob).and_return({})
+ expect(loader.find_subcommands_via_rubygems.values.select { |file| file =~ /knife-ec2/ }.sort).to eq(gem_files)
end
it "finds files using a dirglob when rubygems is not available" do
- expect(@loader.find_subcommands_via_dirglob).to include('chef/knife/node_create')
- @loader.find_subcommands_via_dirglob.each {|rel_path, abs_path| expect(abs_path).to match(%r[chef/knife/.+])}
+ expect(loader.find_subcommands_via_dirglob).to include('chef/knife/node_create')
+ loader.find_subcommands_via_dirglob.each {|rel_path, abs_path| expect(abs_path).to match(%r[chef/knife/.+])}
end
it "finds user-specific subcommands in the user's ~/.chef directory" do
- expected_command = File.join(@home, '.chef', 'plugins', 'knife', 'example_home_subcommand.rb')
- expect(@loader.site_subcommands).to include(expected_command)
+ expected_command = File.join(home, '.chef', 'plugins', 'knife', 'example_home_subcommand.rb')
+ expect(loader.site_subcommands).to include(expected_command)
end
it "finds repo specific subcommands by searching for a .chef directory" do
expected_command = File.join(CHEF_SPEC_DATA, 'knife-site-subcommands', 'plugins', 'knife', 'example_subcommand.rb')
- expect(@loader.site_subcommands).to include(expected_command)
+ expect(loader.site_subcommands).to include(expected_command)
end
# https://github.com/opscode/chef-dk/issues/227
@@ -137,25 +143,19 @@ describe Chef::Knife::SubcommandLoader do
end
before do
- expect(@loader).to receive(:find_files_latest_gems).with("chef/knife/*.rb").and_return(all_found_commands)
- expect(@loader).to receive(:find_subcommands_via_dirglob).and_return({})
+ expect(loader).to receive(:find_files_latest_gems).with("chef/knife/*.rb").and_return(all_found_commands)
+ expect(loader).to receive(:find_subcommands_via_dirglob).and_return({})
end
it "ignores commands from the non-matching gem install" do
- expect(@loader.find_subcommands_via_rubygems.values).to eq(expected_valid_commands)
+ expect(loader.find_subcommands_via_rubygems.values).to eq(expected_valid_commands)
end
end
describe "finding 3rd party plugins" do
- let(:env_home) { "/home/alice" }
- let(:manifest_path) { env_home + "/.chef/plugin_manifest.json" }
-
- before do
- env_dup = ENV.to_hash
- allow(ENV).to receive(:[]) { |key| env_dup[key] }
- allow(ENV).to receive(:[]).with("HOME").and_return(env_home)
- end
+ let(:home) { "/home/alice" }
+ let(:manifest_path) { home + "/.chef/plugin_manifest.json" }
context "when there is not a ~/.chef/plugin_manifest.json file" do
before do
@@ -168,14 +168,14 @@ describe Chef::Knife::SubcommandLoader do
else
expect(Gem.source_index).to receive(:latest_specs).and_call_original
end
- @loader.subcommand_files.each do |require_path|
+ loader.subcommand_files.each do |require_path|
expect(require_path).to match(/chef\/knife\/.*|plugins\/knife\/.*/)
end
end
context "and HOME environment variable is not set" do
before do
- allow(ENV).to receive(:[]).with("HOME").and_return(nil)
+ allow(Chef::Util::PathHelper).to receive(:home).and_return(nil)
end
it "searches rubygems for plugins" do
@@ -184,7 +184,7 @@ describe Chef::Knife::SubcommandLoader do
else
expect(Gem.source_index).to receive(:latest_specs).and_call_original
end
- @loader.subcommand_files.each do |require_path|
+ loader.subcommand_files.each do |require_path|
expect(require_path).to match(/chef\/knife\/.*|plugins\/knife\/.*/)
end
end
@@ -215,7 +215,7 @@ describe Chef::Knife::SubcommandLoader do
it "uses paths from the manifest instead of searching gems" do
expect(Gem::Specification).not_to receive(:latest_specs).and_call_original
- expect(@loader.subcommand_files).to include(ec2_server_create_plugin)
+ expect(loader.subcommand_files).to include(ec2_server_create_plugin)
end
end
diff --git a/spec/unit/mixin/params_validate_spec.rb b/spec/unit/mixin/params_validate_spec.rb
index 85e1c1abab..1b61f9b238 100644
--- a/spec/unit/mixin/params_validate_spec.rb
+++ b/spec/unit/mixin/params_validate_spec.rb
@@ -339,69 +339,83 @@ describe Chef::Mixin::ParamsValidate do
end.to raise_error(Chef::Exceptions::ValidationFailed)
end
- it "should set and return a value, then return the same value" do
- value = "meow"
- expect(@vo.set_or_return(:test, value, {}).object_id).to eq(value.object_id)
- expect(@vo.set_or_return(:test, nil, {}).object_id).to eq(value.object_id)
+ def self.test_set_or_return_method(method)
+ # caller is responsible for passing in the right arg to get 'return' behavior
+ return_arg = method == :nillable_set_or_return ? TinyClass::NULL_ARG : nil
+
+ it "#{method} should set and return a value, then return the same value" do
+ value = "meow"
+ expect(@vo.send(method,:test, value, {}).object_id).to eq(value.object_id)
+ expect(@vo.send(method,:test, return_arg, {}).object_id).to eq(value.object_id)
+ end
+
+ it "#{method} should set and return a default value when the argument is nil, then return the same value" do
+ value = "meow"
+ expect(@vo.send(method,:test, return_arg, { :default => value }).object_id).to eq(value.object_id)
+ expect(@vo.send(method,:test, return_arg, {}).object_id).to eq(value.object_id)
+ end
+
+ it "#{method} should raise an ArgumentError when argument is nil and required is true" do
+ expect {
+ @vo.send(method,:test, return_arg, { :required => true })
+ }.to raise_error(ArgumentError)
+ end
+
+ it "#{method} should not raise an error when argument is nil and required is false" do
+ expect {
+ @vo.send(method,:test, return_arg, { :required => false })
+ }.not_to raise_error
+ end
+
+ it "#{method} should set and return @name, then return @name for foo when argument is nil" do
+ value = "meow"
+ expect(@vo.send(method,:name, value, { }).object_id).to eq(value.object_id)
+ expect(@vo.send(method,:foo, return_arg, { :name_attribute => true }).object_id).to eq(value.object_id)
+ end
+
+ it "#{method} should allow DelayedEvaluator instance to be set for value regardless of restriction" do
+ value = Chef::DelayedEvaluator.new{ 'test' }
+ @vo.send(method,:test, value, {:kind_of => Numeric})
+ end
+
+ it "#{method} should raise an error when delayed evaluated attribute is not valid" do
+ value = Chef::DelayedEvaluator.new{ 'test' }
+ @vo.send(method,:test, value, {:kind_of => Numeric})
+ expect do
+ @vo.send(method,:test, return_arg, {:kind_of => Numeric})
+ end.to raise_error(Chef::Exceptions::ValidationFailed)
+ end
+
+ it "#{method} should create DelayedEvaluator instance when #lazy is used" do
+ @vo.send(method,:delayed, @vo.lazy{ 'test' }, {})
+ expect(@vo.instance_variable_get(:@delayed)).to be_a(Chef::DelayedEvaluator)
+ end
+
+ it "#{method} should execute block on each call when DelayedEvaluator" do
+ value = 'fubar'
+ @vo.send(method,:test, @vo.lazy{ value }, {})
+ expect(@vo.send(method,:test, return_arg, {})).to eq('fubar')
+ value = 'foobar'
+ expect(@vo.send(method,:test, return_arg, {})).to eq('foobar')
+ value = 'fauxbar'
+ expect(@vo.send(method,:test, return_arg, {})).to eq('fauxbar')
+ end
+
+ it "#{method} should not evaluate non DelayedEvaluator instances" do
+ value = lambda{ 'test' }
+ @vo.send(method,:test, value, {})
+ expect(@vo.send(method,:test, return_arg, {}).object_id).to eq(value.object_id)
+ expect(@vo.send(method,:test, return_arg, {})).to be_a(Proc)
+ end
end
- it "should set and return a default value when the argument is nil, then return the same value" do
- value = "meow"
- expect(@vo.set_or_return(:test, nil, { :default => value }).object_id).to eq(value.object_id)
- expect(@vo.set_or_return(:test, nil, {}).object_id).to eq(value.object_id)
- end
-
- it "should raise an ArgumentError when argument is nil and required is true" do
- expect {
- @vo.set_or_return(:test, nil, { :required => true })
- }.to raise_error(ArgumentError)
- end
-
- it "should not raise an error when argument is nil and required is false" do
- expect {
- @vo.set_or_return(:test, nil, { :required => false })
- }.not_to raise_error
- end
-
- it "should set and return @name, then return @name for foo when argument is nil" do
- value = "meow"
- expect(@vo.set_or_return(:name, value, { }).object_id).to eq(value.object_id)
- expect(@vo.set_or_return(:foo, nil, { :name_attribute => true }).object_id).to eq(value.object_id)
- end
+ test_set_or_return_method(:set_or_return)
+ test_set_or_return_method(:nillable_set_or_return)
- it "should allow DelayedEvaluator instance to be set for value regardless of restriction" do
- value = Chef::DelayedEvaluator.new{ 'test' }
- @vo.set_or_return(:test, value, {:kind_of => Numeric})
+ it "nillable_set_or_return supports nilling values" do
+ expect(@vo.nillable_set_or_return(:test, "meow", {})).to eq("meow")
+ expect(@vo.nillable_set_or_return(:test, TinyClass::NULL_ARG, {})).to eq("meow")
+ expect(@vo.nillable_set_or_return(:test, nil, {})).to be_nil
+ expect(@vo.nillable_set_or_return(:test, TinyClass::NULL_ARG, {})).to be_nil
end
-
- it "should raise an error when delayed evaluated attribute is not valid" do
- value = Chef::DelayedEvaluator.new{ 'test' }
- @vo.set_or_return(:test, value, {:kind_of => Numeric})
- expect do
- @vo.set_or_return(:test, nil, {:kind_of => Numeric})
- end.to raise_error(Chef::Exceptions::ValidationFailed)
- end
-
- it "should create DelayedEvaluator instance when #lazy is used" do
- @vo.set_or_return(:delayed, @vo.lazy{ 'test' }, {})
- expect(@vo.instance_variable_get(:@delayed)).to be_a(Chef::DelayedEvaluator)
- end
-
- it "should execute block on each call when DelayedEvaluator" do
- value = 'fubar'
- @vo.set_or_return(:test, @vo.lazy{ value }, {})
- expect(@vo.set_or_return(:test, nil, {})).to eq('fubar')
- value = 'foobar'
- expect(@vo.set_or_return(:test, nil, {})).to eq('foobar')
- value = 'fauxbar'
- expect(@vo.set_or_return(:test, nil, {})).to eq('fauxbar')
- end
-
- it "should not evaluate non DelayedEvaluator instances" do
- value = lambda{ 'test' }
- @vo.set_or_return(:test, value, {})
- expect(@vo.set_or_return(:test, nil, {}).object_id).to eq(value.object_id)
- expect(@vo.set_or_return(:test, nil, {})).to be_a(Proc)
- end
-
end
diff --git a/spec/unit/mixin/powershell_type_coercions_spec.rb b/spec/unit/mixin/powershell_type_coercions_spec.rb
new file mode 100644
index 0000000000..988c3926c1
--- /dev/null
+++ b/spec/unit/mixin/powershell_type_coercions_spec.rb
@@ -0,0 +1,72 @@
+#
+# Author:: Jay Mundrawala (<jdm@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/powershell_type_coercions'
+require 'base64'
+
+class Chef::PSTypeTester
+ include Chef::Mixin::PowershellTypeCoercions
+end
+
+describe Chef::Mixin::PowershellTypeCoercions do
+ let (:test_class) { Chef::PSTypeTester.new }
+
+ describe '#translate_type' do
+ it 'should single quote a string' do
+ expect(test_class.translate_type('foo')).to eq("'foo'")
+ end
+
+ ["'", '"', '#', '`'].each do |c|
+ it "should base64 encode a string that contains #{c}" do
+ expect(test_class.translate_type("#{c}")).to match(Base64.strict_encode64(c))
+ end
+ end
+
+ it 'should not quote an integer' do
+ expect(test_class.translate_type(123)).to eq('123')
+ end
+
+ it 'should not quote a floating point number' do
+ expect(test_class.translate_type(123.4)).to eq('123.4')
+ end
+
+ it 'should return $false when an instance of FalseClass is provided' do
+ expect(test_class.translate_type(false)).to eq('$false')
+ end
+
+ it 'should return $true when an instance of TrueClass is provided' do
+ expect(test_class.translate_type(true)).to eq('$true')
+ end
+
+ it 'should translate all members of a hash and wrap them in @{} separated by ;' do
+ expect(test_class.translate_type({"a" => 1, "b" => 1.2, "c" => false, "d" => true
+ })).to eq("@{a=1;b=1.2;c=$false;d=$true}")
+ end
+
+ it 'should translat all members of an array and them by a ,' do
+ expect(test_class.translate_type([true, false])).to eq('@($true,$false)')
+ end
+
+ it 'should fall back :to_psobject if we have not defined at explicit rule' do
+ ps_obj = double("PSObject")
+ expect(ps_obj).to receive(:to_psobject).and_return('$true')
+ expect(test_class.translate_type(ps_obj)).to eq('($true)')
+ end
+ end
+end
diff --git a/spec/unit/platform/query_helpers_spec.rb b/spec/unit/platform/query_helpers_spec.rb
index 7aafc287ea..1dbd07a021 100644
--- a/spec/unit/platform/query_helpers_spec.rb
+++ b/spec/unit/platform/query_helpers_spec.rb
@@ -53,3 +53,25 @@ describe 'Chef::Platform#supports_dsc?' do
end
end
end
+
+describe 'Chef::Platform#supports_dsc_invoke_resource?' do
+ it 'returns false if powershell is not present' do
+ node = Chef::Node.new
+ expect(Chef::Platform.supports_dsc_invoke_resource?(node)).to be_falsey
+ end
+
+ ['1.0', '2.0', '3.0', '4.0', '5.0.10017.9'].each do |version|
+ it "returns false for Powershell #{version}" do
+ node = Chef::Node.new
+ node.automatic[:languages][:powershell][:version] = version
+ expect(Chef::Platform.supports_dsc_invoke_resource?(node)).to be_falsey
+ end
+ end
+
+ it "returns true for Powershell 5.0.10018.0" do
+ node = Chef::Node.new
+ node.automatic[:languages][:powershell][:version] = "5.0.10018.0"
+ expect(Chef::Platform.supports_dsc_invoke_resource?(node)).to be_truthy
+ end
+end
+
diff --git a/spec/unit/platform_spec.rb b/spec/unit/platform_spec.rb
index fb65ef0fea..e0115bc42a 100644
--- a/spec/unit/platform_spec.rb
+++ b/spec/unit/platform_spec.rb
@@ -20,8 +20,6 @@ require 'spec_helper'
describe "Chef::Platform supports" do
[
- :mac_os_x,
- :mac_os_x_server,
:freebsd,
:ubuntu,
:debian,
@@ -34,9 +32,6 @@ describe "Chef::Platform supports" do
:gentoo,
:arch,
:solaris,
- :mswin,
- :mingw32,
- :windows,
:gcel,
:ibm_powerkvm
].each do |platform|
diff --git a/spec/unit/provider/dsc_resource_spec.rb b/spec/unit/provider/dsc_resource_spec.rb
new file mode 100644
index 0000000000..0a6c22bdcf
--- /dev/null
+++ b/spec/unit/provider/dsc_resource_spec.rb
@@ -0,0 +1,84 @@
+#
+# Author:: Jay Mundrawala (<jdm@chef.io>)
+#
+# Copyright:: Copyright (c) 2014 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 'chef'
+require 'spec_helper'
+
+describe Chef::Provider::DscResource do
+ let (:events) { Chef::EventDispatch::Dispatcher.new }
+ let (:run_context) { Chef::RunContext.new(node, {}, events) }
+ let (:resource) { Chef::Resource::DscResource.new("dscresource", run_context) }
+ let (:provider) do
+ Chef::Provider::DscResource.new(resource, run_context)
+ end
+
+ context 'when Powershell does not support Invoke-DscResource' do
+ let (:node) {
+ node = Chef::Node.new
+ node.automatic[:languages][:powershell][:version] = '4.0'
+ node
+ }
+
+ it 'raises a NoProviderAvailable exception' do
+ expect(provider).not_to receive(:meta_configuration)
+ expect{provider.run_action(:run)}.to raise_error(
+ Chef::Exceptions::NoProviderAvailable, /5\.0\.10018\.0/)
+ end
+ end
+
+ context 'when Powershell supports Invoke-DscResource' do
+ let (:node) {
+ node = Chef::Node.new
+ node.automatic[:languages][:powershell][:version] = '5.0.10018.0'
+ node
+ }
+
+ context 'when RefreshMode is not set to Disabled' do
+ let (:meta_configuration) { {'RefreshMode' => 'AnythingElse'}}
+
+ it 'raises an exception' do
+ expect(provider).to receive(:meta_configuration).and_return(
+ meta_configuration)
+ expect { provider.run_action(:run) }.to raise_error(
+ Chef::Exceptions::NoProviderAvailable, /Disabled/)
+ end
+ end
+
+ context 'when RefreshMode is set to Disabled' do
+ let (:meta_configuration) { {'RefreshMode' => 'Disabled'}}
+
+ it 'does not update the resource if it is up to date' do
+ expect(provider).to receive(:meta_configuration).and_return(
+ meta_configuration)
+ expect(provider).to receive(:test_resource).and_return(true)
+ provider.run_action(:run)
+ expect(resource).not_to be_updated
+ end
+
+ it 'converges the resource if it is not up to date' do
+ expect(provider).to receive(:meta_configuration).and_return(
+ meta_configuration)
+ expect(provider).to receive(:test_resource).and_return(false)
+ expect(provider).to receive(:set_resource)
+ provider.run_action(:run)
+ expect(resource).to be_updated
+ end
+ end
+ end
+end
diff --git a/spec/unit/provider/package/openbsd_spec.rb b/spec/unit/provider/package/openbsd_spec.rb
index ee9c9e89fb..b0cdb9969d 100644
--- a/spec/unit/provider/package/openbsd_spec.rb
+++ b/spec/unit/provider/package/openbsd_spec.rb
@@ -21,28 +21,116 @@ require 'ostruct'
describe Chef::Provider::Package::Openbsd do
+ let(:node) do
+ node = Chef::Node.new
+ node.default['kernel'] = {'name' => 'OpenBSD', 'release' => '5.5', 'machine' => 'amd64'}
+ node
+ end
+
+ let (:provider) do
+ events = Chef::EventDispatch::Dispatcher.new
+ run_context = Chef::RunContext.new(node, {}, events)
+ Chef::Provider::Package::Openbsd.new(new_resource, run_context)
+ end
+
+ let(:new_resource) { Chef::Resource::Package.new(name)}
+
before(:each) do
- @node = Chef::Node.new
- @node.default['kernel'] = {'name' => 'OpenBSD', 'release' => '5.5', 'machine' => 'amd64'}
- @events = Chef::EventDispatch::Dispatcher.new
- @run_context = Chef::RunContext.new(@node, {}, @events)
ENV['PKG_PATH'] = nil
end
describe "install a package" do
- before do
- @name = 'ihavetoes'
- @new_resource = Chef::Resource::Package.new(@name)
- @current_resource = Chef::Resource::Package.new(@name)
- @provider = Chef::Provider::Package::Openbsd.new(@new_resource, @run_context)
- @provider.current_resource = @current_resource
- end
- it "should run the installation command" do
- expect(@provider).to receive(:shell_out!).with(
- "pkg_add -r #{@name}",
- {:env => {"PKG_PATH" => "http://ftp.OpenBSD.org/pub/OpenBSD/5.5/packages/amd64/"}}
- ) {OpenStruct.new :status => true}
- @provider.install_package(@name, nil)
+ let(:name) { 'ihavetoes' }
+ let(:version) {'0.0'}
+
+ context 'when not already installed' do
+ before do
+ allow(provider).to receive(:shell_out!).with("pkg_info -e \"#{name}->0\"", anything()).and_return(instance_double('shellout', :stdout => ''))
+ end
+
+ context 'when there is a single candidate' do
+
+ context 'when installing from source' do
+ it 'should run the installation command' do
+ pending('Installing from source is not supported yet')
+ # This is a consequence of load_current_resource being called before define_resource_requirements
+ # It can be deleted once an implementation is provided
+ allow(provider).to receive(:shell_out!).with("pkg_info -I \"#{name}\"", anything()).and_return(
+ instance_double('shellout', :stdout => "#{name}-#{version}\n"))
+ new_resource.source('/some/path/on/disk.tgz')
+ provider.run_action(:install)
+ end
+ end
+
+ context 'when source is not provided' do
+ it 'should run the installation command' do
+ expect(provider).to receive(:shell_out!).with("pkg_info -I \"#{name}\"", anything()).and_return(
+ instance_double('shellout', :stdout => "#{name}-#{version}\n"))
+ expect(provider).to receive(:shell_out!).with(
+ "pkg_add -r #{name}-#{version}",
+ {:env => {"PKG_PATH" => "http://ftp.OpenBSD.org/pub/OpenBSD/5.5/packages/amd64/"}}
+ ) {OpenStruct.new :status => true}
+ provider.run_action(:install)
+ end
+ end
+ end
+
+ context 'when there are multiple candidates' do
+ let(:flavor_a) { 'flavora' }
+ let(:flavor_b) { 'flavorb' }
+
+ context 'if no version is specified' do
+ it 'should raise an exception' do
+ expect(provider).to receive(:shell_out!).with("pkg_info -I \"#{name}\"", anything()).and_return(
+ instance_double('shellout', :stdout => "#{name}-#{version}-#{flavor_a}\n#{name}-#{version}-#{flavor_b}\n"))
+ expect { provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package, /multiple matching candidates/)
+ end
+ end
+
+ context 'if a flavor is specified' do
+
+ let(:flavor) { 'flavora' }
+ let(:package_name) {'ihavetoes' }
+ let(:name) { "#{package_name}--#{flavor}" }
+
+ context 'if no version is specified' do
+ it 'should run the installation command' do
+ expect(provider).to receive(:shell_out!).with("pkg_info -e \"#{package_name}->0\"", anything()).and_return(instance_double('shellout', :stdout => ''))
+ expect(provider).to receive(:shell_out!).with("pkg_info -I \"#{name}\"", anything()).and_return(
+ instance_double('shellout', :stdout => "#{name}-#{version}-#{flavor}\n"))
+ expect(provider).to receive(:shell_out!).with(
+ "pkg_add -r #{name}-#{version}-#{flavor}",
+ {:env => {"PKG_PATH" => "http://ftp.OpenBSD.org/pub/OpenBSD/5.5/packages/amd64/"}}
+ ) {OpenStruct.new :status => true}
+ provider.run_action(:install)
+ end
+ end
+
+ context 'if a version is specified' do
+ it 'runs the installation command' do
+ pending('Specifying both a version and flavor is not supported')
+ new_resource.version(version)
+ allow(provider).to receive(:shell_out!).with(/pkg_info -e/, anything()).and_return(instance_double('shellout', :stdout => ''))
+ allow(provider).to receive(:candidate_version).and_return("#{package_name}-#{version}-#{flavor}")
+ provider.run_action(:install)
+ end
+ end
+ end
+
+ context 'if a version is specified' do
+ it 'should use the flavor from the version' do
+ expect(provider).to receive(:shell_out!).with("pkg_info -I \"#{name}-#{version}-#{flavor_b}\"", anything()).and_return(
+ instance_double('shellout', :stdout => "#{name}-#{version}-#{flavor_a}\n"))
+
+ new_resource.version("#{version}-#{flavor_b}")
+ expect(provider).to receive(:shell_out!).with(
+ "pkg_add -r #{name}-#{version}-#{flavor_b}",
+ {:env => {"PKG_PATH" => "http://ftp.OpenBSD.org/pub/OpenBSD/5.5/packages/amd64/"}}
+ ) {OpenStruct.new :status => true}
+ provider.run_action(:install)
+ end
+ end
+ end
end
end
diff --git a/spec/unit/provider/service/macosx_spec.rb b/spec/unit/provider/service/macosx_spec.rb
index fb751592df..9905a6e4ae 100644
--- a/spec/unit/provider/service/macosx_spec.rb
+++ b/spec/unit/provider/service/macosx_spec.rb
@@ -22,17 +22,17 @@ describe Chef::Provider::Service::Macosx do
describe ".gather_plist_dirs" do
context "when HOME directory is set" do
before do
- allow(ENV).to receive(:[]).with('HOME').and_return("/User/someuser")
+ allow(Chef::Util::PathHelper).to receive(:home).with('Library', 'LaunchAgents').and_yield('/Users/someuser/Library/LaunchAgents')
end
it "includes users's LaunchAgents folder" do
- expect(described_class.gather_plist_dirs).to include("#{ENV['HOME']}/Library/LaunchAgents")
+ expect(described_class.gather_plist_dirs).to include("/Users/someuser/Library/LaunchAgents")
end
end
context "when HOME directory is not set" do
before do
- allow(ENV).to receive(:[]).with('HOME').and_return(nil)
+ allow(Chef::Util::PathHelper).to receive(:home).with('Library', 'LaunchAgents').and_return(nil)
end
it "doesn't include user's LaunchAgents folder" do
diff --git a/spec/unit/provider_resolver_spec.rb b/spec/unit/provider_resolver_spec.rb
index a9fa08ebfd..63c381f08e 100644
--- a/spec/unit/provider_resolver_spec.rb
+++ b/spec/unit/provider_resolver_spec.rb
@@ -452,6 +452,137 @@ describe Chef::ProviderResolver do
end
+ describe "for the package provider" do
+ let(:resource_name) { :package }
+
+ before do
+ expect(provider_resolver).not_to receive(:maybe_chef_platform_lookup)
+ end
+
+ %w{mac_os_x mac_os_x_server}.each do |platform|
+ describe "on #{platform}" do
+ let(:os) { "darwin" }
+ let(:platform) { platform }
+ let(:platform_family) { "mac_os_x" }
+ let(:platform_version) { "10.9.2" }
+
+
+ it "returns a Chef::Provider::Package::Homebrew provider" do
+ expect(resolved_provider).to eql(Chef::Provider::Package::Homebrew)
+ end
+ end
+ end
+ end
+
+ provider_mapping = {
+ "mac_os_x" => {
+ :package => Chef::Provider::Package::Homebrew,
+ :user => Chef::Provider::User::Dscl,
+ :group => Chef::Provider::Group::Dscl,
+ },
+ "mac_os_x_server" => {
+ :package => Chef::Provider::Package::Homebrew,
+ :user => Chef::Provider::User::Dscl,
+ :group => Chef::Provider::Group::Dscl,
+ },
+ "mswin" => {
+ :env => Chef::Provider::Env::Windows,
+ :user => Chef::Provider::User::Windows,
+ :group => Chef::Provider::Group::Windows,
+ :mount => Chef::Provider::Mount::Windows,
+ :batch => Chef::Provider::Batch,
+ :powershell_script => Chef::Provider::PowershellScript,
+ },
+ "mingw32" => {
+ :env => Chef::Provider::Env::Windows,
+ :user => Chef::Provider::User::Windows,
+ :group => Chef::Provider::Group::Windows,
+ :mount => Chef::Provider::Mount::Windows,
+ :batch => Chef::Provider::Batch,
+ :powershell_script => Chef::Provider::PowershellScript,
+ },
+ "windows" => {
+ :env => Chef::Provider::Env::Windows,
+ :user => Chef::Provider::User::Windows,
+ :group => Chef::Provider::Group::Windows,
+ :mount => Chef::Provider::Mount::Windows,
+ :batch => Chef::Provider::Batch,
+ :powershell_script => Chef::Provider::PowershellScript,
+ },
+ "aix" => {
+ :cron => Chef::Provider::Cron::Aix,
+ },
+ "netbsd"=> {
+ :group => Chef::Provider::Group::Groupmod,
+ },
+ "openbsd" => {
+ :group => Chef::Provider::Group::Usermod,
+ :package => Chef::Provider::Package::Openbsd,
+ },
+ }
+
+ def self.do_platform(platform_hash)
+ platform_hash.each do |resource, provider|
+ describe "for #{resource}" do
+ let(:resource_name) { resource }
+
+ it "resolves to a #{provider}" do
+ expect(resolved_provider).to eql(provider)
+ end
+ end
+ end
+ end
+
+ describe "individual platform mappings" do
+ let(:resource_name) { :user }
+
+ before do
+ expect(provider_resolver).not_to receive(:maybe_chef_platform_lookup)
+ end
+
+ %w{mac_os_x mac_os_x_server}.each do |platform|
+ describe "on #{platform}" do
+ let(:os) { "darwin" }
+ let(:platform) { platform }
+ let(:platform_family) { "mac_os_x" }
+ let(:platform_version) { "10.9.2" }
+
+ do_platform(provider_mapping[platform])
+ end
+ end
+
+ %w{mswin mingw32 windows}.each do |platform|
+ describe "on #{platform}" do
+ let(:os) { "windows" }
+ let(:platform) { platform }
+ let(:platform_family) { "windows" }
+ let(:platform_version) { "10.9.2" }
+
+ do_platform(provider_mapping[platform])
+ end
+ end
+
+ describe "on AIX" do
+ let(:os) { "aix" }
+ let(:platform) { "aix" }
+ let(:platform_family) { "aix" }
+ let(:platform_version) { "6.2" }
+
+ do_platform(provider_mapping['aix'])
+ end
+
+ %w{netbsd openbsd}.each do |platform|
+ describe "on #{platform}" do
+ let(:os) { platform }
+ let(:platform) { platform }
+ let(:platform_family) { platform }
+ let(:platform_version) { "10.0-RELEASE" }
+
+ do_platform(provider_mapping[platform])
+ end
+ end
+ end
+
describe "resolving static providers" do
def resource_class(resource)
Chef::Resource.const_get(convert_to_class_name(resource.to_s))
@@ -481,6 +612,7 @@ describe Chef::ProviderResolver do
link: Chef::Provider::Link,
log: Chef::Provider::Log::ChefLog,
macports_package: Chef::Provider::Package::Macports,
+ mdadm: Chef::Provider::Mdadm,
pacman_package: Chef::Provider::Package::Pacman,
paludis_package: Chef::Provider::Package::Paludis,
perl: Chef::Provider::Script,
diff --git a/spec/unit/recipe_spec.rb b/spec/unit/recipe_spec.rb
index 8d0b1bcfd2..e1604483f3 100644
--- a/spec/unit/recipe_spec.rb
+++ b/spec/unit/recipe_spec.rb
@@ -593,5 +593,9 @@ describe Chef::Recipe do
expect(recipe.singleton_class.included_modules).to include(Chef::DSL::Audit)
expect(recipe.respond_to?(:control_group)).to be true
end
+
+ it "should respond to :ps_credential from Chef::DSL::Powershell" do
+ expect(recipe.respond_to?(:ps_credential)).to be true
+ end
end
end
diff --git a/spec/unit/resource/deploy_spec.rb b/spec/unit/resource/deploy_spec.rb
index 0403a7ba6b..07f5f973c0 100644
--- a/spec/unit/resource/deploy_spec.rb
+++ b/spec/unit/resource/deploy_spec.rb
@@ -30,12 +30,35 @@ describe Chef::Resource::Deploy do
class << self
+
+ def resource_has_a_hash_attribute(attr_name)
+ it "has a Hash attribute for #{attr_name.to_s}" do
+ @resource.send(attr_name, {foo: "bar"})
+ expect(@resource.send(attr_name)).to eql({foo: "bar"})
+ expect {@resource.send(attr_name, 8675309)}.to raise_error(ArgumentError)
+ end
+
+ it "the Hash attribute for #{attr_name.to_s} is nillable" do
+ @resource.send(attr_name, {foo: "bar"})
+ expect(@resource.send(attr_name)).to eql({foo: "bar"})
+ @resource.send(attr_name, nil)
+ expect(@resource.send(attr_name)).to eql(nil)
+ end
+ end
+
def resource_has_a_string_attribute(attr_name)
it "has a String attribute for #{attr_name.to_s}" do
@resource.send(attr_name, "this is a string")
expect(@resource.send(attr_name)).to eql("this is a string")
expect {@resource.send(attr_name, 8675309)}.to raise_error(ArgumentError)
end
+
+ it "the String attribute for #{attr_name.to_s} is nillable" do
+ @resource.send(attr_name, "this is a string")
+ expect(@resource.send(attr_name)).to eql("this is a string")
+ @resource.send(attr_name, nil)
+ expect(@resource.send(attr_name)).to eql(nil)
+ end
end
def resource_has_a_boolean_attribute(attr_name, opts={:defaults_to=>false})
@@ -189,6 +212,10 @@ describe Chef::Resource::Deploy do
expect(@resource.symlink_before_migrate).to eq({"wtf?" => "wtf is going on"})
end
+ resource_has_a_hash_attribute :symlink_before_migrate
+ resource_has_a_hash_attribute :symlinks
+ resource_has_a_hash_attribute :additional_remotes
+
resource_has_a_callback_attribute :before_migrate
resource_has_a_callback_attribute :before_symlink
resource_has_a_callback_attribute :before_restart
diff --git a/spec/unit/resource/dsc_resource_spec.rb b/spec/unit/resource/dsc_resource_spec.rb
new file mode 100644
index 0000000000..ae15f56eaf
--- /dev/null
+++ b/spec/unit/resource/dsc_resource_spec.rb
@@ -0,0 +1,85 @@
+#
+# Author:: Adam Edwards (<adamed@getchef.com>)
+# Copyright:: Copyright (c) 2014 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'
+
+describe Chef::Resource::DscResource do
+ let(:dsc_test_resource_name) { 'DSCTest' }
+ let(:dsc_test_property_name) { :DSCTestProperty }
+ let(:dsc_test_property_value) { 'DSCTestValue' }
+
+ context 'when Powershell supports Dsc' do
+ let(:dsc_test_run_context) {
+ node = Chef::Node.new
+ node.automatic[:languages][:powershell][:version] = '5.0.10018.0'
+ empty_events = Chef::EventDispatch::Dispatcher.new
+ Chef::RunContext.new(node, {}, empty_events)
+ }
+ let(:dsc_test_resource) {
+ Chef::Resource::DscResource.new(dsc_test_resource_name, dsc_test_run_context)
+ }
+
+ it "has a default action of `:run`" do
+ expect(dsc_test_resource.action).to eq(:run)
+ end
+
+ it "has an allowed_actions attribute with only the `:run` and `:nothing` attributes" do
+ expect(dsc_test_resource.allowed_actions.to_set).to eq([:run,:nothing].to_set)
+ end
+
+ it "allows the resource attribute to be set" do
+ dsc_test_resource.resource(dsc_test_resource_name)
+ expect(dsc_test_resource.resource).to eq(dsc_test_resource_name)
+ end
+
+ it "allows the module_name attribute to be set" do
+ dsc_test_resource.module_name(dsc_test_resource_name)
+ expect(dsc_test_resource.module_name).to eq(dsc_test_resource_name)
+ end
+
+ context "when setting a dsc property" do
+ it "allows setting a dsc property with a property name of type Symbol" do
+ dsc_test_resource.property(dsc_test_property_name, dsc_test_property_value)
+ expect(dsc_test_resource.property(dsc_test_property_name)).to eq(dsc_test_property_value)
+ expect(dsc_test_resource.properties[dsc_test_property_name]).to eq(dsc_test_property_value)
+ end
+
+ it "raises a TypeError if property_name is not a symbol" do
+ expect{
+ dsc_test_resource.property('Foo', dsc_test_property_value)
+ }.to raise_error(TypeError)
+ end
+
+ context "when using DelayedEvaluators" do
+ it "allows setting a dsc property with a property name of type Symbol" do
+ dsc_test_resource.property(dsc_test_property_name, Chef::DelayedEvaluator.new {
+ dsc_test_property_value
+ })
+ expect(dsc_test_resource.property(dsc_test_property_name)).to eq(dsc_test_property_value)
+ expect(dsc_test_resource.properties[dsc_test_property_name]).to eq(dsc_test_property_value)
+ end
+ end
+ end
+
+ context 'Powershell DSL methods' do
+ it "responds to :ps_credential" do
+ expect(dsc_test_resource.respond_to?(:ps_credential)).to be true
+ end
+ end
+ end
+end
diff --git a/spec/unit/shell_spec.rb b/spec/unit/shell_spec.rb
index 0e028f4359..617abcfde2 100644
--- a/spec/unit/shell_spec.rb
+++ b/spec/unit/shell_spec.rb
@@ -56,7 +56,7 @@ describe Shell do
describe "configuring IRB" do
it "configures irb history" do
Shell.configure_irb
- expect(Shell.irb_conf[:HISTORY_FILE]).to eq("~/.chef/chef_shell_history")
+ expect(Shell.irb_conf[:HISTORY_FILE]).to eq("#{ENV['HOME']}/.chef/chef_shell_history")
expect(Shell.irb_conf[:SAVE_HISTORY]).to eq(1000)
end
diff --git a/spec/unit/util/dsc/resource_store.rb b/spec/unit/util/dsc/resource_store.rb
new file mode 100644
index 0000000000..a89e73fcaa
--- /dev/null
+++ b/spec/unit/util/dsc/resource_store.rb
@@ -0,0 +1,76 @@
+#
+# Author:: Jay Mundrawala <jdm@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 'chef'
+require 'chef/util/dsc/resource_store'
+
+describe Chef::Util::DSC::ResourceStore do
+ let(:resource_store) { Chef::Util::DSC::ResourceStore.new }
+ let(:resource_a) { {
+ 'ResourceType' => 'AFoo',
+ 'Name' => 'Foo',
+ 'Module' => {'Name' => 'ModuleA'}
+ }
+ }
+
+ let(:resource_b) { {
+ 'ResourceType' => 'BFoo',
+ 'Name' => 'Foo',
+ 'Module' => {'Name' => 'ModuleB'}
+ }
+ }
+
+ context 'when resources are not cached' do
+ context 'when calling #resources' do
+ it 'returns an empty array' do
+ expect(resource_store.resources).to eql([])
+ end
+ end
+
+ context 'when calling #find' do
+ it 'returns an empty list if it cannot find any matching resources' do
+ expect(resource_store).to receive(:query_resource).and_return([])
+ expect(resource_store.find('foo')).to eql([])
+ end
+
+ it 'returns the resource if it is found (comparisons are case insensitive)' do
+ expect(resource_store).to receive(:query_resource).and_return([resource_a])
+ expect(resource_store.find('foo')).to eql([resource_a])
+ end
+
+ it 'returns multiple resoures if they are found' do
+ expect(resource_store).to receive(:query_resource).and_return([resource_a, resource_b])
+ expect(resource_store.find('foo')).to include(resource_a, resource_b)
+ end
+
+ it 'deduplicates resources by ResourceName' do
+ expect(resource_store).to receive(:query_resource).and_return([resource_a, resource_a])
+ resource_store.find('foo')
+ expect(resource_store.resources).to eq([resource_a])
+ end
+ end
+ end
+
+ context 'when resources are cached' do
+ it 'recalls resources from the cache if present' do
+ expect(resource_store).not_to receive(:query_resource)
+ expect(resource_store).to receive(:resources).and_return([resource_a])
+ resource_store.find('foo')
+ end
+ end
+end
diff --git a/spec/unit/util/powershell/ps_credential_spec.rb b/spec/unit/util/powershell/ps_credential_spec.rb
new file mode 100644
index 0000000000..bac58b02e5
--- /dev/null
+++ b/spec/unit/util/powershell/ps_credential_spec.rb
@@ -0,0 +1,37 @@
+#
+# Author:: Jay Mundrawala <jdm@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 'chef'
+require 'chef/util/powershell/ps_credential'
+
+describe Chef::Util::Powershell::PSCredential do
+ let (:username) { 'foo' }
+ let (:password) { 'password' }
+
+ context 'when username and password are provided' do
+ let(:ps_credential) { Chef::Util::Powershell::PSCredential.new(username, password)}
+ context 'when calling to_psobject' do
+ it 'should create the script to create a PSCredential when calling' do
+ allow(ps_credential).to receive(:encrypt).with(password).and_return('encrypted')
+ expect(ps_credential.to_psobject).to eq(
+ "New-Object System.Management.Automation.PSCredential("\
+ "'#{username}',('encrypted' | ConvertTo-SecureString))")
+ end
+ end
+ end
+end
diff --git a/spec/unit/workstation_config_loader_spec.rb b/spec/unit/workstation_config_loader_spec.rb
index a865103188..72631f3dfa 100644
--- a/spec/unit/workstation_config_loader_spec.rb
+++ b/spec/unit/workstation_config_loader_spec.rb
@@ -65,7 +65,7 @@ describe Chef::WorkstationConfigLoader do
let(:home) { "/Users/example.user" }
before do
- env["HOME"] = home
+ allow(Chef::Util::PathHelper).to receive(:home).with('.chef').and_yield(File.join(home, '.chef'))
allow(config_loader).to receive(:path_exists?).with("#{home}/.chef/knife.rb").and_return(true)
end