summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/data/recipes.tgzbin0 -> 293 bytes
-rw-r--r--spec/functional/audit/rspec_formatter_spec.rb5
-rw-r--r--spec/functional/audit/runner_spec.rb15
-rw-r--r--spec/functional/file_content_management/deploy_strategies_spec.rb11
-rw-r--r--spec/functional/knife/exec_spec.rb4
-rw-r--r--spec/functional/resource/execute_spec.rb26
-rw-r--r--spec/functional/resource/powershell_spec.rb15
-rw-r--r--spec/functional/resource/user/useradd_spec.rb23
-rw-r--r--spec/integration/client/client_spec.rb59
-rw-r--r--spec/integration/knife/chef_fs_data_store_spec.rb12
-rw-r--r--spec/integration/knife/download_spec.rb2
-rw-r--r--spec/integration/solo/solo_spec.rb3
-rw-r--r--spec/spec_helper.rb22
-rw-r--r--spec/stress/win32/file_spec.rb4
-rw-r--r--spec/support/audit_helper.rb65
-rw-r--r--spec/support/platform_helpers.rb12
-rw-r--r--spec/unit/api_client_spec.rb76
-rw-r--r--spec/unit/application/apply_spec.rb16
-rw-r--r--spec/unit/application/client_spec.rb27
-rw-r--r--spec/unit/application/solo_spec.rb5
-rw-r--r--spec/unit/application_spec.rb35
-rw-r--r--spec/unit/audit/audit_event_proxy_spec.rb4
-rw-r--r--spec/unit/audit/runner_spec.rb14
-rw-r--r--spec/unit/chef_fs/config_spec.rb52
-rw-r--r--spec/unit/chef_fs/file_pattern_spec.rb2
-rw-r--r--spec/unit/config_spec.rb39
-rw-r--r--spec/unit/cookbook_loader_spec.rb14
-rw-r--r--spec/unit/cookbook_manifest_spec.rb609
-rw-r--r--spec/unit/cookbook_uploader_spec.rb40
-rw-r--r--spec/unit/cookbook_version_file_specificity_spec.rb554
-rw-r--r--spec/unit/cookbook_version_spec.rb256
-rw-r--r--spec/unit/data_bag_item_spec.rb202
-rw-r--r--spec/unit/deprecation_spec.rb39
-rw-r--r--spec/unit/dsl/audit_spec.rb8
-rw-r--r--spec/unit/encrypted_data_bag_item_spec.rb24
-rw-r--r--spec/unit/knife/client_create_spec.rb96
-rw-r--r--spec/unit/knife/cookbook_site_share_spec.rb17
-rw-r--r--spec/unit/knife/cookbook_upload_spec.rb68
-rw-r--r--spec/unit/knife/raw_spec.rb43
-rw-r--r--spec/unit/knife/role_env_run_list_add_spec.rb217
-rw-r--r--spec/unit/knife/role_env_run_list_clear_spec.rb100
-rw-r--r--spec/unit/knife/role_env_run_list_remove_spec.rb108
-rw-r--r--spec/unit/knife/role_env_run_list_replace_spec.rb108
-rw-r--r--spec/unit/knife/role_env_run_list_set_spec.rb102
-rw-r--r--spec/unit/knife/role_run_list_add_spec.rb179
-rw-r--r--spec/unit/knife/role_run_list_clear_spec.rb90
-rw-r--r--spec/unit/knife/role_run_list_remove_spec.rb98
-rw-r--r--spec/unit/knife/role_run_list_replace_spec.rb101
-rw-r--r--spec/unit/knife/role_run_list_set_spec.rb92
-rw-r--r--spec/unit/lwrp_spec.rb36
-rw-r--r--spec/unit/org_spec.rb196
-rw-r--r--spec/unit/policy_builder/policyfile_spec.rb220
-rw-r--r--spec/unit/provider/env_spec.rb23
-rw-r--r--spec/unit/provider/package/aix_spec.rb2
-rw-r--r--spec/unit/provider/package/apt_spec.rb8
-rw-r--r--spec/unit/provider/package/dpkg_spec.rb2
-rw-r--r--spec/unit/provider/package/ips_spec.rb3
-rw-r--r--spec/unit/provider/package/rpm_spec.rb216
-rw-r--r--spec/unit/provider/package/rubygems_spec.rb70
-rw-r--r--spec/unit/provider/package/solaris_spec.rb2
-rw-r--r--spec/unit/provider/package/yum_spec.rb139
-rw-r--r--spec/unit/provider/package_spec.rb276
-rw-r--r--spec/unit/provider/package_spec.rbe0
-rw-r--r--spec/unit/provider/service/freebsd_service_spec.rb14
-rw-r--r--spec/unit/provider/service/openbsd_service_spec.rb543
-rw-r--r--spec/unit/provider/user_spec.rb2
-rw-r--r--spec/unit/recipe_spec.rb2
-rw-r--r--spec/unit/resource/chef_gem_spec.rb70
-rw-r--r--spec/unit/resource/conditional_spec.rb50
-rw-r--r--spec/unit/resource/execute_spec.rb4
-rw-r--r--spec/unit/resource/rpm_package_spec.rb12
-rw-r--r--spec/unit/resource_spec.rb14
-rw-r--r--spec/unit/util/diff_spec.rb12
-rw-r--r--spec/unit/util/dsc/local_configuration_manager_spec.rb10
-rw-r--r--spec/unit/util/path_helper_spec.rb12
75 files changed, 4384 insertions, 1267 deletions
diff --git a/spec/data/recipes.tgz b/spec/data/recipes.tgz
new file mode 100644
index 0000000000..a6c172a001
--- /dev/null
+++ b/spec/data/recipes.tgz
Binary files differ
diff --git a/spec/functional/audit/rspec_formatter_spec.rb b/spec/functional/audit/rspec_formatter_spec.rb
index 43d3c2f6dd..009374db68 100644
--- a/spec/functional/audit/rspec_formatter_spec.rb
+++ b/spec/functional/audit/rspec_formatter_spec.rb
@@ -19,9 +19,10 @@
#
require 'spec_helper'
-require 'spec/support/audit_helper'
+require 'rspec/core/sandbox'
require 'chef/audit/runner'
require 'rspec/support/spec/in_sub_process'
+require 'rspec/support/spec/stderr_splitter'
require 'chef/audit/rspec_formatter'
describe Chef::Audit::RspecFormatter do
@@ -37,7 +38,7 @@ describe Chef::Audit::RspecFormatter do
let!(:formatter) { Chef::Audit::RspecFormatter.new(output) }
around(:each) do |ex|
- Sandboxing.sandboxed { ex.run }
+ RSpec::Core::Sandbox.sandboxed { ex.run }
end
it "should not close the output using our formatter" do
diff --git a/spec/functional/audit/runner_spec.rb b/spec/functional/audit/runner_spec.rb
index aa35548f2f..494942889a 100644
--- a/spec/functional/audit/runner_spec.rb
+++ b/spec/functional/audit/runner_spec.rb
@@ -17,9 +17,10 @@
#
require 'spec_helper'
-require 'spec/support/audit_helper'
+require 'rspec/core/sandbox'
require 'chef/audit/runner'
require 'rspec/support/spec/in_sub_process'
+require 'rspec/support/spec/stderr_splitter'
require 'tempfile'
##
@@ -42,7 +43,7 @@ describe Chef::Audit::Runner do
let(:stdout) { StringIO.new }
around(:each) do |ex|
- Sandboxing.sandboxed { ex.run }
+ RSpec::Core::Sandbox.sandboxed { ex.run }
end
before do
@@ -53,7 +54,7 @@ describe Chef::Audit::Runner do
let(:audits) { {} }
let(:run_context) { instance_double(Chef::RunContext, :events => events, :audits => audits) }
- let(:controls_name) { "controls_name" }
+ let(:control_group_name) { "control_group_name" }
it "Correctly runs an empty controls block" do
in_sub_process do
@@ -68,7 +69,7 @@ describe Chef::Audit::Runner do
expect(2 - 2).to eq(0)
end
end
- { controls_name => Struct.new(:args, :block).new([controls_name], should_pass)}
+ { control_group_name => Struct.new(:args, :block).new([control_group_name], should_pass)}
end
end
@@ -79,7 +80,7 @@ describe Chef::Audit::Runner do
expect(2 - 1).to eq(0)
end
end
- { controls_name => Struct.new(:args, :block).new([controls_name], should_fail)}
+ { control_group_name => Struct.new(:args, :block).new([control_group_name], should_fail)}
end
end
@@ -102,7 +103,7 @@ describe Chef::Audit::Runner do
expect(stdout.string).to match(/Failure\/Error: expect\(2 - 1\)\.to eq\(0\)/)
expect(stdout.string).to match(/1 example, 1 failure/)
- expect(stdout.string).to match(/# controls_name should fail/)
+ expect(stdout.string).to match(/# control_group_name should fail/)
end
end
end
@@ -126,7 +127,7 @@ describe Chef::Audit::Runner do
contents = tmpfile.read
expect(contents).to match(/Failure\/Error: expect\(2 - 1\)\.to eq\(0\)/)
expect(contents).to match(/1 example, 1 failure/)
- expect(contents).to match(/# controls_name should fail/)
+ expect(contents).to match(/# control_group_name should fail/)
end
end
end
diff --git a/spec/functional/file_content_management/deploy_strategies_spec.rb b/spec/functional/file_content_management/deploy_strategies_spec.rb
index bcd171eb73..03a6c504c1 100644
--- a/spec/functional/file_content_management/deploy_strategies_spec.rb
+++ b/spec/functional/file_content_management/deploy_strategies_spec.rb
@@ -20,15 +20,6 @@ require 'spec_helper'
shared_examples_for "a content deploy strategy" do
- # Ruby 1.8 has no binread
- def binread(file)
- if IO.respond_to?(:binread)
- IO.binread(file)
- else
- IO.read(file)
- end
- end
-
def normalize_mode(mode_int)
( mode_int & 07777).to_s(8)
end
@@ -160,7 +151,7 @@ shared_examples_for "a content deploy strategy" do
it "updates the target with content from staged" do
content_deployer.deploy(staging_file_path, target_file_path)
- expect(binread(target_file_path)).to eq(staging_file_content)
+ expect(IO.binread(target_file_path)).to eq(staging_file_content)
end
context "when the owner of the target file is not the owner of the staging file", :requires_root do
diff --git a/spec/functional/knife/exec_spec.rb b/spec/functional/knife/exec_spec.rb
index 0a9177b5e8..6262094a9f 100644
--- a/spec/functional/knife/exec_spec.rb
+++ b/spec/functional/knife/exec_spec.rb
@@ -41,9 +41,7 @@ describe Chef::Knife::Exec do
@server.stop
end
- skip "executes a script in the context of the chef-shell main context", :ruby_18_only
-
- it "executes a script in the context of the chef-shell main context", :ruby_gte_19_only do
+ it "executes a script in the context of the chef-shell main context" do
@node = Chef::Node.new
@node.name("ohai-world")
response = {"rows" => [@node],"start" => 0,"total" => 1}
diff --git a/spec/functional/resource/execute_spec.rb b/spec/functional/resource/execute_spec.rb
index 020814fcd6..aaa1c772b7 100644
--- a/spec/functional/resource/execute_spec.rb
+++ b/spec/functional/resource/execute_spec.rb
@@ -35,6 +35,32 @@ describe Chef::Resource::Execute do
end
end
+ describe "when why_run is enabled" do
+ before do
+ Chef::Config[:why_run] = true
+ end
+
+ let(:guard) { "ruby -e 'exit 0'" }
+ let!(:guard_resource) {
+ interpreter = Chef::GuardInterpreter::ResourceGuardInterpreter.new(resource, guard, nil)
+ interpreter.send(:get_interpreter_resource, resource)
+ }
+
+ it "executes the guard and not the regular resource" do
+ expect_any_instance_of(Chef::GuardInterpreter::ResourceGuardInterpreter).to receive(:get_interpreter_resource).and_return(guard_resource)
+
+ # why_run mode doesn't disable the updated_by_last_action logic, so we really have to look at the provider action
+ # to see if why_run correctly disabled the resource. It should shell_out! for the guard but not the resource.
+ expect_any_instance_of(Chef::Provider::Execute).to receive(:shell_out!).once
+
+ resource.only_if guard
+ resource.run_action(:run)
+
+ expect(resource).to be_updated_by_last_action
+ expect(guard_resource).to be_updated_by_last_action
+ end
+ end
+
describe "when parent resource sets :cwd" do
let(:guard) { %{ruby -e 'exit 1 unless File.exists?("./big_json_plus_one.json")'} }
diff --git a/spec/functional/resource/powershell_spec.rb b/spec/functional/resource/powershell_spec.rb
index 033f34e256..1b3ac844e0 100644
--- a/spec/functional/resource/powershell_spec.rb
+++ b/spec/functional/resource/powershell_spec.rb
@@ -56,6 +56,21 @@ 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
+ file = Tempfile.new(['foo', '.ps1'])
+ begin
+ file.write "exit -27"
+ file.close
+ resource.code(". \"#{file.path}\"")
+ resource.returns(-27)
+ resource.run_action(:run)
+ ensure
+ file.close
+ file.unlink
+ end
+ end
+
+
it "returns the process exit code" do
resource.code(arbitrary_nonzero_process_exit_code_content)
resource.returns(arbitrary_nonzero_process_exit_code)
diff --git a/spec/functional/resource/user/useradd_spec.rb b/spec/functional/resource/user/useradd_spec.rb
index 6b962c19aa..9ac88d7b60 100644
--- a/spec/functional/resource/user/useradd_spec.rb
+++ b/spec/functional/resource/user/useradd_spec.rb
@@ -82,12 +82,25 @@ describe Chef::Provider::User::Useradd, metadata do
end
after do
- begin
- pw_entry # will raise if the user doesn't exist
- shell_out!("userdel", "-r", username, :returns => [0,12])
- rescue UserNotFound
- # nothing to remove
+ max_retries = 3
+ while max_retries > 0
+ begin
+ pw_entry # will raise if the user doesn't exist
+ status = shell_out!("userdel", "-r", username, :returns => [0,8,12])
+
+ # Error code 8 during userdel indicates that the user is logged in.
+ # This occurs randomly because the accounts daemon holds a lock due to which userdel fails.
+ # The work around is to retry userdel for 3 times.
+ break if status.exitstatus != 8
+
+ sleep 1
+ max_retries = max_retries -1
+ rescue UserNotFound
+ break
+ end
end
+
+ status.error! if max_retries == 0
end
let(:node) do
diff --git a/spec/integration/client/client_spec.rb b/spec/integration/client/client_spec.rb
index 62660bb852..8afb52e29a 100644
--- a/spec/integration/client/client_spec.rb
+++ b/spec/integration/client/client_spec.rb
@@ -1,5 +1,34 @@
require 'support/shared/integration/integration_helper'
require 'chef/mixin/shell_out'
+require 'tiny_server'
+require 'tmpdir'
+
+def recipes_filename
+ File.join(CHEF_SPEC_DATA, 'recipes.tgz')
+end
+
+def start_tiny_server(server_opts={})
+ recipes_size = File::Stat.new(recipes_filename).size
+ @server = TinyServer::Manager.new(server_opts)
+ @server.start
+ @api = TinyServer::API.instance
+ @api.clear
+ #
+ # trivial endpoints
+ #
+ # just a normal file
+ # (expected_content should be uncompressed)
+ @api.get("/recipes.tgz", 200) {
+ File.open(recipes_filename, "rb") do |f|
+ f.read
+ end
+ }
+end
+
+def stop_tiny_server
+ @server.stop
+ @server = @api = nil
+end
describe "chef-client" do
include IntegrationSupport
@@ -252,7 +281,7 @@ EOM
it "should exit with a zero code when there is not an audit failure" do
file 'cookbooks/audit_test/recipes/succeed.rb', <<-RECIPE
-controls "control group without top level control" do
+control_group "control group without top level control" do
it "should succeed" do
expect(2 - 2).to eq(0)
end
@@ -261,12 +290,12 @@ end
result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" -o 'audit_test::succeed'", :cwd => chef_dir)
expect(result.error?).to be_falsey
- expect(result.stdout).to include("Successfully executed all `controls` blocks and contained examples")
+ expect(result.stdout).to include("Successfully executed all `control_group` blocks and contained examples")
end
it "should exit with a non-zero code when there is an audit failure" do
file 'cookbooks/audit_test/recipes/fail.rb', <<-RECIPE
-controls "control group without top level control" do
+control_group "control group without top level control" do
it "should fail" do
expect(2 - 2).to eq(1)
end
@@ -279,4 +308,28 @@ end
end
end
+ context "when using recipe-url" do
+ before(:all) do
+ start_tiny_server
+ end
+
+ after(:all) do
+ stop_tiny_server
+ end
+
+ let(:tmp_dir) { Dir.mktmpdir("recipe-url") }
+
+ it "should complete with success when passed -z and --recipe-url" do
+ file 'config/client.rb', <<EOM
+chef_repo_path "#{tmp_dir}"
+EOM
+ result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" --recipe-url=http://localhost:9000/recipes.tgz -o 'x::default' -z", :cwd => tmp_dir)
+ result.error!
+ end
+
+ it 'should fail when passed --recipe-url and not passed -z' do
+ result = shell_out("#{chef_client} --recipe-url=http://localhost:9000/recipes.tgz", :cwd => tmp_dir)
+ expect(result.exitstatus).to eq(1)
+ end
+ end
end
diff --git a/spec/integration/knife/chef_fs_data_store_spec.rb b/spec/integration/knife/chef_fs_data_store_spec.rb
index eb02db5384..c1f2c7134f 100644
--- a/spec/integration/knife/chef_fs_data_store_spec.rb
+++ b/spec/integration/knife/chef_fs_data_store_spec.rb
@@ -138,6 +138,7 @@ EOM
context 'PUT /TYPE/NAME' do
before do
file 'empty.json', {}
+ file 'dummynode.json', { "name" => "x", "chef_environment" => "rspec" , "json_class" => "Chef::Node", "normal" => {"foo" => "bar"}}
file 'rolestuff.json', '{"description":"hi there","name":"x"}'
file 'cookbooks_to_upload/x/metadata.rb', cookbook_x_100_metadata_rb
end
@@ -165,9 +166,10 @@ EOM
knife('list --local /environments').should_succeed "/environments/x.json\n"
end
- it 'knife raw -z -i empty.json -m PUT /nodes/x' do
- knife("raw -z -i #{path_to('empty.json')} -m PUT /nodes/x").should_succeed( /"x"/ )
+ it 'knife raw -z -i dummynode.json -m PUT /nodes/x' do
+ knife("raw -z -i #{path_to('dummynode.json')} -m PUT /nodes/x").should_succeed( /"x"/ )
knife('list --local /nodes').should_succeed "/nodes/x.json\n"
+ knife('show -z /nodes/x.json --verbose').should_succeed /"bar"/
end
it 'knife raw -z -i empty.json -m PUT /roles/x' do
@@ -196,6 +198,7 @@ EOM
context 'POST /TYPE/NAME' do
before do
file 'empty.json', { 'name' => 'z' }
+ file 'dummynode.json', { "name" => "z", "chef_environment" => "rspec" , "json_class" => "Chef::Node", "normal" => {"foo" => "bar"}}
file 'empty_x.json', { 'name' => 'x' }
file 'empty_id.json', { 'id' => 'z' }
file 'rolestuff.json', '{"description":"hi there","name":"x"}'
@@ -231,9 +234,10 @@ EOM
knife('list --local /environments').should_succeed "/environments/z.json\n"
end
- it 'knife raw -z -i empty.json -m POST /nodes' do
- knife("raw -z -i #{path_to('empty.json')} -m POST /nodes").should_succeed( /uri/ )
+ it 'knife raw -z -i dummynode.json -m POST /nodes' do
+ knife("raw -z -i #{path_to('dummynode.json')} -m POST /nodes").should_succeed( /uri/ )
knife('list --local /nodes').should_succeed "/nodes/z.json\n"
+ knife('show -z /nodes/z.json').should_succeed /"bar"/
end
it 'knife raw -z -i empty.json -m POST /roles' do
diff --git a/spec/integration/knife/download_spec.rb b/spec/integration/knife/download_spec.rb
index cf1e4fcf0f..c87e6fe20a 100644
--- a/spec/integration/knife/download_spec.rb
+++ b/spec/integration/knife/download_spec.rb
@@ -1069,7 +1069,7 @@ EOM
end
when_the_repository 'is empty' do
- it 'knife download /cookbooks/x signs all requests', :ruby_gte_19_only do
+ it 'knife download /cookbooks/x signs all requests' do
# Check that BasicClient.request() always gets called with X-OPS-USERID
original_new = Chef::HTTP::BasicClient.method(:new)
diff --git a/spec/integration/solo/solo_spec.rb b/spec/integration/solo/solo_spec.rb
index cc9ba1abb2..41f5f5506f 100644
--- a/spec/integration/solo/solo_spec.rb
+++ b/spec/integration/solo/solo_spec.rb
@@ -83,8 +83,7 @@ end
EOM
end
- # Ruby 1.8.7 doesn't have Process.spawn :(
- it "while running solo concurrently", :ruby_gte_19_only => true do
+ it "while running solo concurrently" do
file 'config/solo.rb', <<EOM
cookbook_path "#{path_to('cookbooks')}"
file_cache_path "#{path_to('config/cache')}"
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 995be5060b..8888efc424 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -83,8 +83,13 @@ Dir["spec/support/**/*.rb"].
OHAI_SYSTEM = Ohai::System.new
OHAI_SYSTEM.all_plugins("platform")
-TEST_PLATFORM = OHAI_SYSTEM["platform"].dup.freeze
-TEST_PLATFORM_VERSION = OHAI_SYSTEM["platform_version"].dup.freeze
+
+TEST_PLATFORM =
+ (OHAI_SYSTEM['platform'] ||
+ 'unknown_test_platform').dup.freeze
+TEST_PLATFORM_VERSION =
+ (OHAI_SYSTEM['platform_version'] ||
+ 'unknown_platform_version').dup.freeze
RSpec.configure do |config|
config.include(Matchers)
@@ -124,11 +129,7 @@ RSpec.configure do |config|
config.filter_run_excluding :aix_only => true unless aix?
config.filter_run_excluding :supports_cloexec => true unless supports_cloexec?
config.filter_run_excluding :selinux_only => true unless selinux_enabled?
- config.filter_run_excluding :ruby_18_only => true unless ruby_18?
- config.filter_run_excluding :ruby_19_only => true unless ruby_19?
- config.filter_run_excluding :ruby_gte_19_only => true unless ruby_gte_19?
config.filter_run_excluding :ruby_20_only => true unless ruby_20?
- config.filter_run_excluding :ruby_gte_20_only => true unless ruby_gte_20?
# chef_gte_XX_only and chef_lt_XX_only pair up correctly with the same XX
# number. please conserve this pattern & resist filling out all the operators
config.filter_run_excluding :chef_gte_13_only => true unless chef_gte_13?
@@ -137,9 +138,8 @@ RSpec.configure do |config|
config.filter_run_excluding :requires_root_or_running_windows => true unless (root? || windows?)
config.filter_run_excluding :requires_unprivileged_user => true if root?
config.filter_run_excluding :uses_diff => true unless has_diff?
- config.filter_run_excluding :ruby_gte_20_and_openssl_gte_101 => true unless (ruby_gte_20? && openssl_gte_101?)
+ config.filter_run_excluding :openssl_gte_101 => true unless openssl_gte_101?
config.filter_run_excluding :openssl_lt_101 => true unless openssl_lt_101?
- config.filter_run_excluding :ruby_lt_20 => true unless ruby_lt_20?
config.filter_run_excluding :aes_256_gcm_only => true unless aes_256_gcm?
config.filter_run_excluding :broken => true
@@ -169,6 +169,12 @@ RSpec.configure do |config|
config.before(:each) do
Chef::Config.reset
+
+ # By default, treat deprecation warnings as errors in tests.
+ Chef::Config.treat_deprecation_warnings_as_errors(true)
+
+ # Set environment variable so the setting persists in child processes
+ ENV['CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS'] = "1"
end
config.before(:suite) do
diff --git a/spec/stress/win32/file_spec.rb b/spec/stress/win32/file_spec.rb
index dd1dcd305e..6c4b26b05c 100644
--- a/spec/stress/win32/file_spec.rb
+++ b/spec/stress/win32/file_spec.rb
@@ -24,12 +24,12 @@ describe 'Chef::ReservedNames::Win32::File', :windows_only do
@path = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "data", "old_home_dir", "my-dot-emacs"))
end
- it "should not leak significant memory" do
+ it "should not leak significant memory", :volatile do
test = lambda { Chef::ReservedNames::Win32::File.symlink?(@path) }
expect(test).not_to leak_memory(:warmup => 50000, :iterations => 50000)
end
- it "should not leak handles" do
+ it "should not leak handles", :volatile do
test = lambda { Chef::ReservedNames::Win32::File.symlink?(@path) }
expect(test).not_to leak_handles(:warmup => 50, :iterations => 100)
end
diff --git a/spec/support/audit_helper.rb b/spec/support/audit_helper.rb
deleted file mode 100644
index 8fd3f4d719..0000000000
--- a/spec/support/audit_helper.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-# This code comes from https://github.com/rspec/rspec-core/blob/master/spec/spec_helper.rb and
-# https://github.com/rspec/rspec-core/blob/master/spec/support/sandboxing.rb
-
-# To leverage the sandboxing use an `around` block:
-# around(:each) do |ex|
-# Sandboxing.sandboxed { ex.run }
-# end
-
-# rspec-core did not include a license on Github
-# TODO when this API is exposed publicly from rspec-core, get rid of this copy pasta
-
-# Adding these as writers is necessary, otherwise we cannot set the new configuration.
-# Only want to do this in the specs.
-class << RSpec
- attr_writer :configuration, :world
-end
-
-class NullObject
- private
- def method_missing(method, *args, &block)
- # ignore
- end
-end
-
-# TODO remove this when RSPec exposes this functionality publically
-# https://github.com/rspec/rspec-core/pull/1808
-module Sandboxing
- def self.sandboxed(&block)
- orig_load_path = $LOAD_PATH.dup
- orig_config = RSpec.configuration
- orig_world = RSpec.world
- orig_example = RSpec.current_example
- new_config = RSpec::Core::Configuration.new
- new_config.expose_dsl_globally = false
- new_config.expecting_with_rspec = true
- new_world = RSpec::Core::World.new(new_config)
- RSpec.configuration = new_config
- RSpec.world = new_world
- object = Object.new
- object.extend(RSpec::Core::SharedExampleGroup)
-
- (class << RSpec::Core::ExampleGroup; self; end).class_exec do
- alias_method :orig_run, :run
- def run(reporter=nil)
- RSpec.current_example = nil
- orig_run(reporter || NullObject.new)
- end
- end
-
- RSpec::Mocks.with_temporary_scope do
- object.instance_exec(&block)
- end
- ensure
- (class << RSpec::Core::ExampleGroup; self; end).class_exec do
- remove_method :run
- alias_method :run, :orig_run
- remove_method :orig_run
- end
-
- RSpec.configuration = orig_config
- RSpec.world = orig_world
- RSpec.current_example = orig_example
- $LOAD_PATH.replace(orig_load_path)
- end
-end
diff --git a/spec/support/platform_helpers.rb b/spec/support/platform_helpers.rb
index 959580c953..a412fe38e1 100644
--- a/spec/support/platform_helpers.rb
+++ b/spec/support/platform_helpers.rb
@@ -6,10 +6,6 @@ class ShellHelpers
extend Chef::Mixin::ShellOut
end
-def ruby_gte_20?
- RUBY_VERSION.to_f >= 2.0
-end
-
def ruby_lt_20?
!ruby_gte_20?
end
@@ -30,14 +26,6 @@ def ruby_20?
!!(RUBY_VERSION =~ /^2.0/)
end
-def ruby_19?
- !!(RUBY_VERSION =~ /^1.9/)
-end
-
-def ruby_18?
- !!(RUBY_VERSION =~ /^1.8/)
-end
-
def windows?
!!(RUBY_PLATFORM =~ /mswin|mingw|windows/)
end
diff --git a/spec/unit/api_client_spec.rb b/spec/unit/api_client_spec.rb
index 7f8687e2b9..7668e31f5a 100644
--- a/spec/unit/api_client_spec.rb
+++ b/spec/unit/api_client_spec.rb
@@ -129,43 +129,83 @@ describe Chef::ApiClient do
end
end
- describe "when deserializing from JSON" do
- before(:each) do
- client = {
- "name" => "black",
- "public_key" => "crowes",
- "private_key" => "monkeypants",
- "admin" => true,
- "validator" => true,
- "json_class" => "Chef::ApiClient"
- }
- @client = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(client))
+ describe "when deserializing from JSON (string) using ApiClient#from_json" do
+ let(:client_string) do
+ "{\"name\":\"black\",\"public_key\":\"crowes\",\"private_key\":\"monkeypants\",\"admin\":true,\"validator\":true}"
+ end
+
+ let(:client) do
+ Chef::ApiClient.from_json(client_string)
+ end
+
+ it "does not require a 'json_class' string" do
+ expect(Chef::JSONCompat.parse(client_string)["json_class"]).to eq(nil)
end
it "should deserialize to a Chef::ApiClient object" do
- expect(@client).to be_a_kind_of(Chef::ApiClient)
+ expect(client).to be_a_kind_of(Chef::ApiClient)
end
it "preserves the name" do
- expect(@client.name).to eq("black")
+ expect(client.name).to eq("black")
end
it "preserves the public key" do
- expect(@client.public_key).to eq("crowes")
+ expect(client.public_key).to eq("crowes")
end
it "preserves the admin status" do
- expect(@client.admin).to be_truthy
+ expect(client.admin).to be_truthy
end
it "preserves the 'validator' status" do
- expect(@client.validator).to be_truthy
+ expect(client.validator).to be_truthy
end
it "includes the private key if present" do
- expect(@client.private_key).to eq("monkeypants")
+ expect(client.private_key).to eq("monkeypants")
+ end
+ end
+
+ describe "when deserializing from JSON (hash) using JSONCompat#from_json" do
+ let(:client_hash) do
+ {
+ "name" => "black",
+ "public_key" => "crowes",
+ "private_key" => "monkeypants",
+ "admin" => true,
+ "validator" => true,
+ "json_class" => "Chef::ApiClient"
+ }
end
+ let(:client) do
+ Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(client_hash))
+ end
+
+ it "should deserialize to a Chef::ApiClient object" do
+ expect(client).to be_a_kind_of(Chef::ApiClient)
+ end
+
+ it "preserves the name" do
+ expect(client.name).to eq("black")
+ end
+
+ it "preserves the public key" do
+ expect(client.public_key).to eq("crowes")
+ end
+
+ it "preserves the admin status" do
+ expect(client.admin).to be_truthy
+ end
+
+ it "preserves the 'validator' status" do
+ expect(client.validator).to be_truthy
+ end
+
+ it "includes the private key if present" do
+ expect(client.private_key).to eq("monkeypants")
+ end
end
describe "when loading from JSON" do
@@ -306,5 +346,3 @@ describe Chef::ApiClient do
end
end
end
-
-
diff --git a/spec/unit/application/apply_spec.rb b/spec/unit/application/apply_spec.rb
index 5a6366281f..f6cd0bae03 100644
--- a/spec/unit/application/apply_spec.rb
+++ b/spec/unit/application/apply_spec.rb
@@ -91,4 +91,20 @@ describe Chef::Application::Apply do
end
end
+ describe "when the json_attribs configuration option is specified" do
+ let(:json_attribs) { {"a" => "b"} }
+ let(:config_fetcher) { double(Chef::ConfigFetcher, :fetch_json => json_attribs) }
+ let(:json_source) { "https://foo.com/foo.json" }
+
+ before do
+ Chef::Config[:json_attribs] = json_source
+ expect(Chef::ConfigFetcher).to receive(:new).with(json_source).
+ and_return(config_fetcher)
+ end
+
+ it "reads the JSON attributes from the specified source" do
+ @app.reconfigure
+ expect(@app.json_attribs).to eq(json_attribs)
+ end
+ end
end
diff --git a/spec/unit/application/client_spec.rb b/spec/unit/application/client_spec.rb
index 33af9bc5c1..ea2ad473e5 100644
--- a/spec/unit/application/client_spec.rb
+++ b/spec/unit/application/client_spec.rb
@@ -26,6 +26,7 @@ describe Chef::Application::Client, "reconfigure" do
before do
allow(Kernel).to receive(:trap).and_return(:ok)
+ allow(::File).to receive(:read).with(Chef::Config.platform_specific_path("/etc/chef/client.rb")).and_return("")
@original_argv = ARGV.dup
ARGV.clear
@@ -41,6 +42,13 @@ describe Chef::Application::Client, "reconfigure" do
ARGV.replace(@original_argv)
end
+ describe 'parse cli_arguments' do
+ it 'should call set_specific_recipes' do
+ expect(app).to receive(:set_specific_recipes).and_return(true)
+ app.reconfigure
+ end
+ end
+
describe "when configured to not fork the client process" do
before do
Chef::Config[:client_fork] = false
@@ -215,8 +223,21 @@ Enable chef-client interval runs by setting `:client_fork = true` in your config
end
end
end
+
+ describe "when both the pidfile and lockfile opts are set to the same value" do
+
+ before do
+ Chef::Config[:pid_file] = "/path/to/file"
+ Chef::Config[:lockfile] = "/path/to/file"
+ end
+
+ it "should throw an exception" do
+ expect { @app.reconfigure }.to raise_error
+ end
+ end
end
+
describe Chef::Application::Client, "setup_application" do
before do
@app = Chef::Application::Client.new
@@ -236,11 +257,13 @@ describe Chef::Application::Client, "setup_application" do
end
describe Chef::Application::Client, "configure_chef" do
+ let(:app) { Chef::Application::Client.new }
+
before do
@original_argv = ARGV.dup
ARGV.clear
- @app = Chef::Application::Client.new
- @app.configure_chef
+ allow(::File).to receive(:read).with(Chef::Config.platform_specific_path("/etc/chef/client.rb")).and_return("")
+ app.configure_chef
end
after do
diff --git a/spec/unit/application/solo_spec.rb b/spec/unit/application/solo_spec.rb
index 2a07ff38ad..1785ecfc86 100644
--- a/spec/unit/application/solo_spec.rb
+++ b/spec/unit/application/solo_spec.rb
@@ -34,6 +34,11 @@ describe Chef::Application::Solo do
end
describe "configuring the application" do
+ it 'should call set_specific_recipes' do
+ expect(app).to receive(:set_specific_recipes)
+ app.reconfigure
+ end
+
it "should set solo mode to true" do
app.reconfigure
expect(Chef::Config[:solo]).to be_truthy
diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb
index 210f875fbe..f5a2c72aa0 100644
--- a/spec/unit/application_spec.rb
+++ b/spec/unit/application_spec.rb
@@ -56,6 +56,11 @@ describe Chef::Application do
expect(@app).to receive(:configure_proxy_environment_variables).and_return(true)
@app.reconfigure
end
+
+ it 'should not receive set_specific_recipes' do
+ expect(@app).to_not receive(:set_specific_recipes)
+ @app.reconfigure
+ end
end
describe Chef::Application do
@@ -473,6 +478,36 @@ describe Chef::Application do
end
end
+ describe 'run_chef_client' do
+ context 'with an application' do
+ let(:app) { Chef::Application.new }
+
+ context 'when called with an invalid argument' do
+ before do
+ allow(app).to receive(:fork_chef_client).and_return(true)
+ allow(app).to receive(:run_with_graceful_exit_option).and_return(true)
+ end
+
+ it 'should raise an argument error detailing the problem' do
+ specific_recipes_regexp = Regexp.new 'received non-Array like specific_recipes argument'
+ expect { app.run_chef_client(nil) }.to raise_error(ArgumentError, specific_recipes_regexp)
+ end
+ end
+
+ context 'when called with an Array-like argument (#size)' do
+ before do
+ allow(app).to receive(:fork_chef_client).and_return(true)
+ allow(app).to receive(:run_with_graceful_exit_option).and_return(true)
+ end
+
+ it 'should be cool' do
+ expect { app.run_chef_client([]) }.not_to raise_error
+ end
+ end
+ end
+
+ end
+
describe "configuration errors" do
before do
expect(Process).to receive(:exit)
diff --git a/spec/unit/audit/audit_event_proxy_spec.rb b/spec/unit/audit/audit_event_proxy_spec.rb
index 899ba468b1..17a5d3d771 100644
--- a/spec/unit/audit/audit_event_proxy_spec.rb
+++ b/spec/unit/audit/audit_event_proxy_spec.rb
@@ -44,7 +44,7 @@ describe Chef::Audit::AuditEventProxy do
it "notifies control_group_started event" do
expect(Chef::Log).to receive(:debug).
- with("Entered \`controls\` block named poots")
+ with("Entered \`control_group\` block named poots")
expect(events).to receive(:control_group_started).
with(description)
audit_event_proxy.example_group_started(notification)
@@ -76,7 +76,7 @@ describe Chef::Audit::AuditEventProxy do
end
it "sends a message that audits completed" do
- expect(Chef::Log).to receive(:info).with("Successfully executed all \`controls\` blocks and contained examples")
+ expect(Chef::Log).to receive(:info).with("Successfully executed all \`control_group\` blocks and contained examples")
audit_event_proxy.stop(notification)
end
diff --git a/spec/unit/audit/runner_spec.rb b/spec/unit/audit/runner_spec.rb
index 67590fecf9..801147bdb9 100644
--- a/spec/unit/audit/runner_spec.rb
+++ b/spec/unit/audit/runner_spec.rb
@@ -17,11 +17,13 @@
#
require 'spec_helper'
-require 'spec/support/audit_helper'
+require 'rspec/core/sandbox'
require 'chef/audit/runner'
require 'chef/audit/audit_event_proxy'
require 'chef/audit/rspec_formatter'
require 'rspec/support/spec/in_sub_process'
+require 'rspec/support/spec/stderr_splitter'
+
describe Chef::Audit::Runner do
include RSpec::Support::InSubProcess
@@ -31,7 +33,7 @@ describe Chef::Audit::Runner do
let(:runner) { Chef::Audit::Runner.new(run_context) }
around(:each) do |ex|
- Sandboxing.sandboxed { ex.run }
+ RSpec::Core::Sandbox.sandboxed { ex.run }
end
describe "#initialize" do
@@ -76,14 +78,14 @@ describe Chef::Audit::Runner do
end
end
- describe "#register_controls" do
+ describe "#register_control_groups" do
let(:audits) { [] }
let(:run_context) { instance_double(Chef::RunContext, :audits => audits) }
it "adds the control group aliases" do
- runner.send(:register_controls)
+ runner.send(:register_control_groups)
- expect(RSpec::Core::DSL.example_group_aliases).to include(:__controls__)
+ expect(RSpec::Core::DSL.example_group_aliases).to include(:__control_group__)
expect(RSpec::Core::DSL.example_group_aliases).to include(:control)
end
@@ -92,7 +94,7 @@ describe Chef::Audit::Runner do
let(:group) {Struct.new(:args, :block).new(["group_name"], nil)}
it "sends the audits to the world" do
- runner.send(:register_controls)
+ runner.send(:register_control_groups)
expect(RSpec.world.example_groups.size).to eq(1)
# For whatever reason, `kind_of` is not working
diff --git a/spec/unit/chef_fs/config_spec.rb b/spec/unit/chef_fs/config_spec.rb
index 031da6c4b5..c7c47ad8ab 100644
--- a/spec/unit/chef_fs/config_spec.rb
+++ b/spec/unit/chef_fs/config_spec.rb
@@ -55,4 +55,56 @@ describe Chef::ChefFS::Config do
Chef::ChefFS::Config.new(base_config, Dir.pwd, {}, ui)
end
end
+
+ describe "local FS configuration" do
+
+ let(:chef_config) do
+ Mash.new({
+ client_path: "/base_path/clients",
+ cookbook_path: "/base_path/cookbooks",
+ data_bag_path: "/base_path/data_bags",
+ environment_path: "/base_path/environments",
+ node_path: "/base_path/nodes",
+ role_path: "/base_path/roles",
+ user_path: "/base_path/users",
+ policy_path: "/base_path/policies"
+ })
+ end
+
+ let(:chef_fs_config) { Chef::ChefFS::Config.new(chef_config, Dir.pwd) }
+
+ subject(:local_fs) { chef_fs_config.local_fs }
+
+ def platform_path(*args)
+ File.expand_path(*args)
+ end
+
+ it "sets the correct nodes path on the local FS object" do
+ expect(local_fs.child_paths["nodes"]).to eq([platform_path("/base_path/nodes")])
+ end
+
+ it "sets the correct cookbook path on the local FS object" do
+ expect(local_fs.child_paths["cookbooks"]).to eq([platform_path("/base_path/cookbooks")])
+ end
+
+ it "sets the correct data bag path on the local FS object" do
+ expect(local_fs.child_paths["data_bags"]).to eq([platform_path("/base_path/data_bags")])
+ end
+
+ it "sets the correct environment path on the local FS object" do
+ expect(local_fs.child_paths["environments"]).to eq([platform_path("/base_path/environments")])
+ end
+
+ it "sets the correct role path on the local FS object" do
+ expect(local_fs.child_paths["roles"]).to eq([platform_path("/base_path/roles")])
+ end
+
+ it "sets the correct user path on the local FS object" do
+ expect(local_fs.child_paths["users"]).to eq([platform_path("/base_path/users")])
+ end
+
+ it "sets the correct policy path on the local FS object" do
+ expect(local_fs.child_paths["policies"]).to eq([platform_path("/base_path/policies")])
+ end
+ end
end
diff --git a/spec/unit/chef_fs/file_pattern_spec.rb b/spec/unit/chef_fs/file_pattern_spec.rb
index cdf506225a..a9f06e8424 100644
--- a/spec/unit/chef_fs/file_pattern_spec.rb
+++ b/spec/unit/chef_fs/file_pattern_spec.rb
@@ -355,7 +355,7 @@ describe Chef::ChefFS::FilePattern do
it 'could_match_children? /abc** returns false for /xyz' do
pending 'Make could_match_children? more rigorous'
# At the moment, we return false for this, but in the end it would be nice to return true:
- pattern.could_match_children?('/xyz').should be_falsey
+ expect(pattern.could_match_children?('/xyz')).to be_falsey
end
it 'exact_child_name_under' do
expect(pattern.exact_child_name_under('/')).to eq(nil)
diff --git a/spec/unit/config_spec.rb b/spec/unit/config_spec.rb
index ed2003e8bf..06178f7733 100644
--- a/spec/unit/config_spec.rb
+++ b/spec/unit/config_spec.rb
@@ -508,4 +508,43 @@ describe Chef::Config do
end
end
end
+
+ describe "Treating deprecation warnings as errors" do
+
+ context "when using our default RSpec configuration" do
+
+ it "defaults to treating deprecation warnings as errors" do
+ expect(Chef::Config[:treat_deprecation_warnings_as_errors]).to be(true)
+ end
+
+ it "sets CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS environment variable" do
+ expect(ENV['CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS']).to eq("1")
+ end
+
+ it "treats deprecation warnings as errors in child processes when testing" do
+ # Doing a full integration test where we launch a child process is slow
+ # and liable to break for weird reasons (bundler env stuff, etc.), so
+ # we're just checking that the presence of the environment variable
+ # causes treat_deprecation_warnings_as_errors to be set to true after a
+ # config reset.
+ Chef::Config.reset
+ expect(Chef::Config[:treat_deprecation_warnings_as_errors]).to be(true)
+ end
+
+ end
+
+ context "outside of our test environment" do
+
+ before do
+ ENV.delete('CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS')
+ Chef::Config.reset
+ end
+
+ it "defaults to NOT treating deprecation warnings as errors" do
+ expect(Chef::Config[:treat_deprecation_warnings_as_errors]).to be(false)
+ end
+ end
+
+
+ end
end
diff --git a/spec/unit/cookbook_loader_spec.rb b/spec/unit/cookbook_loader_spec.rb
index 51532778e4..45a985bafd 100644
--- a/spec/unit/cookbook_loader_spec.rb
+++ b/spec/unit/cookbook_loader_spec.rb
@@ -190,6 +190,11 @@ describe Chef::CookbookLoader do
end
describe "loading only one cookbook" do
+
+ let(:openldap_cookbook) { cookbook_loader["openldap"] }
+
+ let(:cookbook_as_hash) { Chef::CookbookManifest.new(openldap_cookbook).to_hash }
+
before(:each) do
cookbook_loader.load_cookbook("openldap")
end
@@ -205,12 +210,11 @@ describe Chef::CookbookLoader do
it "should not duplicate keys when serialized to JSON" do
# Chef JSON serialization will generate duplicate keys if given
# a Hash containing matching string and symbol keys. See CHEF-4571.
- aa = cookbook_loader["openldap"]
- expect(aa.to_hash["metadata"].recipes.keys).not_to include(:openldap)
- expect(aa.to_hash["metadata"].recipes.keys).to include("openldap")
+ expect(cookbook_as_hash["metadata"].recipes.keys).not_to include(:openldap)
+ expect(cookbook_as_hash["metadata"].recipes.keys).to include("openldap")
expected_desc = "Main Open LDAP configuration"
- expect(aa.to_hash["metadata"].recipes["openldap"]).to eq(expected_desc)
- raw = Chef::JSONCompat.to_json(aa.to_hash["metadata"].recipes)
+ expect(cookbook_as_hash["metadata"].recipes["openldap"]).to eq(expected_desc)
+ raw = Chef::JSONCompat.to_json(cookbook_as_hash["metadata"].recipes)
search_str = "\"openldap\":\""
key_idx = raw.index(search_str)
expect(key_idx).to be > 0
diff --git a/spec/unit/cookbook_manifest_spec.rb b/spec/unit/cookbook_manifest_spec.rb
index 8b50b040c2..938f72c743 100644
--- a/spec/unit/cookbook_manifest_spec.rb
+++ b/spec/unit/cookbook_manifest_spec.rb
@@ -1,7 +1,6 @@
#
-# Author:: Tim Hinderliter (<tim@opscode.com>)
-# Author:: Christopher Walters (<cw@opscode.com>)
-# Copyright:: Copyright (c) 2010 Opscode, Inc.
+# Author:: Daniel DeLeo (<dan@chef.io>)
+# Copyright:: Copyright (c) 2015 Opscode, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,540 +14,214 @@
# 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/cookbook_manifest'
+require 'chef/digester'
+require 'pathname'
-describe "Chef::CookbookVersion manifest" do
- before(:each) do
- @cookbook = Chef::CookbookVersion.new "test-cookbook"
- @cookbook.manifest = {
- "files" =>
- [
- # afile.rb
- {
- :name => "afile.rb",
- :path => "files/host-examplehost.example.org/afile.rb",
- :checksum => "csum-host",
- :specificity => "host-examplehost.example.org"
- },
- {
- :name => "afile.rb",
- :path => "files/ubuntu-9.10/afile.rb",
- :checksum => "csum-platver-full",
- :specificity => "ubuntu-9.10"
- },
- {
- :name => "afile.rb",
- :path => "files/newubuntu-9/afile.rb",
- :checksum => "csum-platver-partial",
- :specificity => "newubuntu-9"
- },
- {
- :name => "afile.rb",
- :path => "files/ubuntu/afile.rb",
- :checksum => "csum-plat",
- :specificity => "ubuntu"
- },
- {
- :name => "afile.rb",
- :path => "files/default/afile.rb",
- :checksum => "csum-default",
- :specificity => "default"
- },
-
- # for different/odd platform_versions
- {
- :name => "bfile.rb",
- :path => "files/fakeos-2.0.rc.1/bfile.rb",
- :checksum => "csum2-platver-full",
- :specificity => "fakeos-2.0.rc.1"
- },
- {
- :name => "bfile.rb",
- :path => "files/newfakeos-2.0.rc/bfile.rb",
- :checksum => "csum2-platver-partial",
- :specificity => "newfakeos-2.0.rc"
- },
- {
- :name => "bfile.rb",
- :path => "files/fakeos-maple tree/bfile.rb",
- :checksum => "csum3-platver-full",
- :specificity => "maple tree"
- },
- {
- :name => "bfile.rb",
- :path => "files/fakeos-1/bfile.rb",
- :checksum => "csum4-platver-full",
- :specificity => "fakeos-1"
- },
-
- # directory adirectory
- {
- :name => "anotherfile1.rb",
- :path => "files/host-examplehost.example.org/adirectory/anotherfile1.rb.host",
- :checksum => "csum-host-1",
- :specificity => "host-examplehost.example.org"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/host-examplehost.example.org/adirectory/anotherfile2.rb.host",
- :checksum => "csum-host-2",
- :specificity => "host-examplehost.example.org"
- },
-
- {
- :name => "anotherfile1.rb",
- :path => "files/ubuntu-9.10/adirectory/anotherfile1.rb.platform-full-version",
- :checksum => "csum-platver-full-1",
- :specificity => "ubuntu-9.10"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/ubuntu-9.10/adirectory/anotherfile2.rb.platform-full-version",
- :checksum => "csum-platver-full-2",
- :specificity => "ubuntu-9.10"
- },
-
- {
- :name => "anotherfile1.rb",
- :path => "files/newubuntu-9/adirectory/anotherfile1.rb.platform-partial-version",
- :checksum => "csum-platver-partial-1",
- :specificity => "newubuntu-9"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/newubuntu-9/adirectory/anotherfile2.rb.platform-partial-version",
- :checksum => "csum-platver-partial-2",
- :specificity => "nweubuntu-9"
- },
-
- {
- :name => "anotherfile1.rb",
- :path => "files/ubuntu/adirectory/anotherfile1.rb.platform",
- :checksum => "csum-plat-1",
- :specificity => "ubuntu"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/ubuntu/adirectory/anotherfile2.rb.platform",
- :checksum => "csum-plat-2",
- :specificity => "ubuntu"
- },
-
- {
- :name => "anotherfile1.rb",
- :path => "files/default/adirectory/anotherfile1.rb.default",
- :checksum => "csum-default-1",
- :specificity => "default"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/default/adirectory/anotherfile2.rb.default",
- :checksum => "csum-default-2",
- :specificity => "default"
- },
- # for different/odd platform_versions
- {
- :name => "anotherfile1.rb",
- :path => "files/fakeos-2.0.rc.1/adirectory/anotherfile1.rb.platform-full-version",
- :checksum => "csum2-platver-full-1",
- :specificity => "fakeos-2.0.rc.1"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/fakeos-2.0.rc.1/adirectory/anotherfile2.rb.platform-full-version",
- :checksum => "csum2-platver-full-2",
- :specificity => "fakeos-2.0.rc.1"
- },
- {
- :name => "anotherfile1.rb",
- :path => "files/newfakeos-2.0.rc.1/adirectory/anotherfile1.rb.platform-partial-version",
- :checksum => "csum2-platver-partial-1",
- :specificity => "newfakeos-2.0.rc"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/newfakeos-2.0.rc.1/adirectory/anotherfile2.rb.platform-partial-version",
- :checksum => "csum2-platver-partial-2",
- :specificity => "newfakeos-2.0.rc"
- },
- {
- :name => "anotherfile1.rb",
- :path => "files/fakeos-maple tree/adirectory/anotherfile1.rb.platform-full-version",
- :checksum => "csum3-platver-full-1",
- :specificity => "fakeos-maple tree"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/fakeos-maple tree/adirectory/anotherfile2.rb.platform-full-version",
- :checksum => "csum3-platver-full-2",
- :specificity => "fakeos-maple tree"
- },
- {
- :name => "anotherfile1.rb",
- :path => "files/fakeos-1/adirectory/anotherfile1.rb.platform-full-version",
- :checksum => "csum4-platver-full-1",
- :specificity => "fakeos-1"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/fakeos-1/adirectory/anotherfile2.rb.platform-full-version",
- :checksum => "csum4-platver-full-2",
- :specificity => "fakeos-1"
- },
- ]
- }
-
- end
-
-
- it "should return a manifest record based on priority preference: host" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "examplehost.example.org"
-
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
- expect(manifest_record).not_to be_nil
- expect(manifest_record[:checksum]).to eq("csum-host")
- end
-
- it "should return a manifest record based on priority preference: platform & full version" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
- expect(manifest_record).not_to be_nil
- expect(manifest_record[:checksum]).to eq("csum-platver-full")
- end
-
- it "should return a manifest record based on priority preference: platform & partial version" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "newubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
- expect(manifest_record).not_to be_nil
- expect(manifest_record[:checksum]).to eq("csum-platver-partial")
- end
+describe Chef::CookbookManifest do
- it "should return a manifest record based on priority preference: platform only" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "1.0"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ let(:version) { "1.2.3" }
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
- expect(manifest_record).not_to be_nil
- expect(manifest_record[:checksum]).to eq("csum-plat")
- end
-
- it "should return a manifest record based on priority preference: default" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "notubuntu"
- node.automatic_attrs[:platform_version] = "1.0"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
- expect(manifest_record).not_to be_nil
- expect(manifest_record[:checksum]).to eq("csum-default")
+ let(:metadata) do
+ Chef::Cookbook::Metadata.new.tap do |m|
+ m.version(version)
+ end
end
- it "should return a manifest record based on priority preference: platform & full version - platform_version variant 1" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "2.0.rc.1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ let(:cookbook_root) { '/tmp/blah' }
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
- expect(manifest_record).not_to be_nil
- expect(manifest_record[:checksum]).to eq("csum2-platver-full")
+ let(:cookbook_version) do
+ Chef::CookbookVersion.new("tatft", cookbook_root).tap do |c|
+ c.metadata = metadata
+ end
end
- it "should return a manifest record based on priority preference: platform & partial version - platform_version variant 1" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "newfakeos"
- node.automatic_attrs[:platform_version] = "2.0.rc.1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ let(:policy_mode) { false }
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
- expect(manifest_record).not_to be_nil
- expect(manifest_record[:checksum]).to eq("csum2-platver-partial")
- end
+ subject(:cookbook_manifest) { Chef::CookbookManifest.new(cookbook_version, policy_mode: policy_mode) }
- it "should return a manifest record based on priority preference: platform & full version - platform_version variant 2" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "maple tree"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ context "when policy mode is not specified" do
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
- expect(manifest_record).not_to be_nil
- expect(manifest_record[:checksum]).to eq("csum3-platver-full")
- end
+ subject(:cookbook_manifest) { Chef::CookbookManifest.new(cookbook_version) }
- it "should return a manifest record based on priority preference: platform & full version - platform_version variant 3" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ it "defaults to policies disabled" do
+ expect(cookbook_manifest.policy_mode?).to be(false)
+ end
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
- expect(manifest_record).not_to be_nil
- expect(manifest_record[:checksum]).to eq("csum4-platver-full")
end
- describe "when fetching the contents of a directory by file specificity" do
-
- it "should return a directory of manifest records based on priority preference: host" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "examplehost.example.org"
+ describe "collecting cookbook data from the cookbook version object" do
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- expect(manifest_records).not_to be_nil
- expect(manifest_records.size).to eq(2)
-
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- expect(checksums.sort).to eq(["csum-host-1", "csum-host-2"])
+ it "delegates `name' to cookbook_version" do
+ expect(cookbook_manifest.name).to eq("tatft")
end
- it "should return a directory of manifest records based on priority preference: platform & full version" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- expect(manifest_records).not_to be_nil
- expect(manifest_records.size).to eq(2)
-
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- expect(checksums.sort).to eq(["csum-platver-full-1", "csum-platver-full-2"])
+ it "delegates `root_paths' to cookbook_version" do
+ expect(cookbook_manifest.root_paths).to eq(['/tmp/blah'])
end
- it "should return a directory of manifest records based on priority preference: platform & partial version" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "newubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- expect(manifest_records).not_to be_nil
- expect(manifest_records.size).to eq(2)
-
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- expect(checksums.sort).to eq(["csum-platver-partial-1", "csum-platver-partial-2"])
+ it "delegates `metadata' to cookbook_version" do
+ expect(cookbook_manifest.metadata).to eq(metadata)
end
- it "should return a directory of manifest records based on priority preference: platform only" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "1.0"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- expect(manifest_records).not_to be_nil
- expect(manifest_records.size).to eq(2)
-
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- expect(checksums.sort).to eq(["csum-plat-1", "csum-plat-2"])
+ it "delegates `full_name' to cookbook_version" do
+ expect(cookbook_manifest.full_name).to eq("tatft-1.2.3")
end
- it "should return a directory of manifest records based on priority preference: default" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "notubuntu"
- node.automatic_attrs[:platform_version] = "1.0"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- expect(manifest_records).not_to be_nil
- expect(manifest_records.size).to eq(2)
-
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- expect(checksums.sort).to eq(["csum-default-1", "csum-default-2"])
+ it "delegates `version' to cookbook_version" do
+ expect(cookbook_manifest.version).to eq(version)
end
- it "should return a manifest record based on priority preference: platform & full version - platform_version variant 1" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "2.0.rc.1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- expect(manifest_records).not_to be_nil
- expect(manifest_records.size).to eq(2)
+ it "delegates `frozen_version?' to cookbook_version" do
+ expect(cookbook_manifest.frozen_version?).to be(false)
+ end
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- expect(checksums.sort).to eq(["csum2-platver-full-1", "csum2-platver-full-2"])
+ it "delegates `segment_filenames' to cookbook_version" do
+ expect(cookbook_version).to receive(:segment_filenames).with(:recipes).and_return([])
+ expect(cookbook_manifest.segment_filenames(:recipes)).to eq([])
end
- it "should return a manifest record based on priority preference: platform & partial version - platform_version variant 1" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "newfakeos"
- node.automatic_attrs[:platform_version] = "2.0.rc.1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ end
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- expect(manifest_records).not_to be_nil
- expect(manifest_records.size).to eq(2)
+ context "when given an empty cookbook" do
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- expect(checksums.sort).to eq(["csum2-platver-partial-1", "csum2-platver-partial-2"])
- end
+ let(:expected_hash) do
+ {
+ "chef_type" => "cookbook_version",
- it "should return a manifest record based on priority preference: platform & full version - platform_version variant 2" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "maple tree"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ "name" => "tatft-1.2.3",
+ "version" => "1.2.3",
+ "cookbook_name" => "tatft",
+ "metadata" => metadata,
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- expect(manifest_records).not_to be_nil
- expect(manifest_records.size).to eq(2)
+ "frozen?" => false,
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- expect(checksums.sort).to eq(["csum3-platver-full-1", "csum3-platver-full-2"])
+ "recipes" =>[],
+ "definitions" =>[],
+ "libraries" =>[],
+ "attributes" =>[],
+ "files" =>[],
+ "templates" =>[],
+ "resources" =>[],
+ "providers" =>[],
+ "root_files" =>[],
+ }
end
- it "should return a manifest record based on priority preference: platform & full version - platform_version variant 3" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- expect(manifest_records).not_to be_nil
- expect(manifest_records.size).to eq(2)
-
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- expect(checksums.sort).to eq(["csum4-platver-full-1", "csum4-platver-full-2"])
+ it "converts the CookbookVersion to a ruby Hash representation" do
+ expect(cookbook_manifest.to_hash).to eq(expected_hash)
end
+
end
- ## Globbing the relative paths out of the manifest records ##
+ context "when given a cookbook with files" do
- describe "when globbing for relative file paths based on filespecificity" do
- it "should return a list of relative paths based on priority preference: host" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "examplehost.example.org"
+ let(:cookbook_root) { File.join(CHEF_SPEC_DATA, 'cb_version_cookbooks', 'tatft') }
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- expect(filenames).not_to be_nil
- expect(filenames.size).to eq(2)
+ let(:attribute_filenames) { Dir[File.join(cookbook_root, 'attributes', '**', '*.rb')] }
+ let(:definition_filenames) { Dir[File.join(cookbook_root, 'definitions', '**', '*.rb')] }
+ let(:file_filenames) { Dir[File.join(cookbook_root, 'files', '**', '*.tgz')] }
+ let(:recipe_filenames) { Dir[File.join(cookbook_root, 'recipes', '**', '*.rb')] }
+ let(:template_filenames) { Dir[File.join(cookbook_root, 'templates', '**', '*.erb')] }
+ let(:library_filenames) { Dir[File.join(cookbook_root, 'libraries', '**', '*.rb')] }
+ let(:resource_filenames) { Dir[File.join(cookbook_root, 'resources', '**', '*.rb')] }
+ let(:provider_filenames) { Dir[File.join(cookbook_root, 'providers', '**', '*.rb')] }
+ let(:root_filenames) { Array(File.join(cookbook_root, 'README.rdoc')) }
+ let(:metadata_filenames) { Array(File.join(cookbook_root, 'metadata.json')) }
- expect(filenames.sort).to eq(['anotherfile1.rb.host', 'anotherfile2.rb.host'])
- end
+ let(:match_md5) { /[0-9a-f]{32}/ }
- it "should return a list of relative paths based on priority preference: platform & full version" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ def map_to_file_specs(paths)
+ paths.map do |path|
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- expect(filenames).not_to be_nil
- expect(filenames.size).to eq(2)
+ relative_path = Pathname.new(path).relative_path_from(Pathname.new(cookbook_root)).to_s
- expect(filenames.sort).to eq(['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version'])
+ {
+ "name" => File.basename(path),
+ "path" => relative_path,
+ "checksum" => Chef::Digester.generate_md5_checksum_for_file(path),
+ "specificity" => "default",
+ }
+ end
end
- it "should return a list of relative paths based on priority preference: platform & partial version" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "newubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- expect(filenames).not_to be_nil
- expect(filenames.size).to eq(2)
+ let(:expected_hash) do
+ {
+ "chef_type" => "cookbook_version",
- expect(filenames.sort).to eq(['anotherfile1.rb.platform-partial-version', 'anotherfile2.rb.platform-partial-version'])
- end
-
- it "should return a list of relative paths based on priority preference: platform only" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "1.0"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ "name" => "tatft-1.2.3",
+ "version" => "1.2.3",
+ "cookbook_name" => "tatft",
+ "metadata" => metadata,
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- expect(filenames).not_to be_nil
- expect(filenames.size).to eq(2)
+ "frozen?" => false,
- expect(filenames.sort).to eq(['anotherfile1.rb.platform', 'anotherfile2.rb.platform'])
+ "recipes" => map_to_file_specs(recipe_filenames),
+ "definitions" => map_to_file_specs(definition_filenames),
+ "libraries" => map_to_file_specs(library_filenames),
+ "attributes" => map_to_file_specs(attribute_filenames),
+ "files" => map_to_file_specs(file_filenames),
+ "templates" => map_to_file_specs(template_filenames),
+ "resources" => map_to_file_specs(resource_filenames),
+ "providers" => map_to_file_specs(provider_filenames),
+ "root_files" => map_to_file_specs(root_filenames),
+ }
end
- it "should return a list of relative paths based on priority preference: default" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "notubuntu"
- node.automatic_attrs[:platform_version] = "1.0"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ before do
+ cookbook_version.attribute_filenames = attribute_filenames
+ cookbook_version.definition_filenames = definition_filenames
+ cookbook_version.file_filenames = file_filenames
+ cookbook_version.recipe_filenames = recipe_filenames
+ cookbook_version.template_filenames = template_filenames
+ cookbook_version.library_filenames = library_filenames
+ cookbook_version.resource_filenames = resource_filenames
+ cookbook_version.provider_filenames = provider_filenames
+ cookbook_version.root_filenames = root_filenames
+ cookbook_version.metadata_filenames = metadata_filenames
+ end
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- expect(filenames).not_to be_nil
- expect(filenames.size).to eq(2)
+ it "converts the CookbookVersion to a ruby Hash representation" do
+ cookbook_manifest_hash = cookbook_manifest.to_hash
- expect(filenames.sort).to eq(['anotherfile1.rb.default', 'anotherfile2.rb.default'])
+ expect(cookbook_manifest_hash.keys).to match_array(expected_hash.keys)
+ cookbook_manifest_hash.each do |key, value|
+ expect(cookbook_manifest_hash[key]).to eq(expected_hash[key])
+ end
end
- it "should return a list of relative paths based on priority preference: platform & full version - platform_version variant 1" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "2.0.rc.1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ end
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- expect(filenames).not_to be_nil
- expect(filenames.size).to eq(2)
+ describe "providing upstream URLs for save" do
- expect(filenames.sort).to eq(['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version'])
- end
+ context "and policy mode is disabled" do
- it "should return a list of relative paths based on priority preference: platform & partial version - platform_version variant 1" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "newfakeos"
- node.automatic_attrs[:platform_version] = "2.0.rc.1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ it "gives the save URL" do
+ expect(cookbook_manifest.save_url).to eq("cookbooks/tatft/1.2.3")
+ end
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- expect(filenames).not_to be_nil
- expect(filenames.size).to eq(2)
+ it "gives the force save URL" do
+ expect(cookbook_manifest.force_save_url).to eq("cookbooks/tatft/1.2.3?force=true")
+ end
- expect(filenames.sort).to eq(['anotherfile1.rb.platform-partial-version', 'anotherfile2.rb.platform-partial-version'])
end
- it "should return a list of relative paths based on priority preference: platform & full version - platform_version variant 2" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "maple tree"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- expect(filenames).not_to be_nil
- expect(filenames.size).to eq(2)
+ context "and policy mode is enabled" do
- expect(filenames.sort).to eq(['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version'])
- end
+ let(:policy_mode) { true }
- it "should return a list of relative paths based on priority preference: platform & full version - platform_version variant 3" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ it "gives the save URL" do
+ expect(cookbook_manifest.save_url).to eq("cookbook_artifacts/tatft/1.2.3")
+ end
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- expect(filenames).not_to be_nil
- expect(filenames.size).to eq(2)
+ it "gives the force save URL" do
+ expect(cookbook_manifest.force_save_url).to eq("cookbook_artifacts/tatft/1.2.3?force=true")
+ end
- expect(filenames.sort).to eq(['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version'])
end
end
+
end
+
diff --git a/spec/unit/cookbook_uploader_spec.rb b/spec/unit/cookbook_uploader_spec.rb
index af25baff13..152e5373f0 100644
--- a/spec/unit/cookbook_uploader_spec.rb
+++ b/spec/unit/cookbook_uploader_spec.rb
@@ -45,7 +45,13 @@ describe Chef::CookbookUploader do
let(:sandbox_commit_uri) { "https://chef.example.org/sandboxes/abc123" }
- let(:uploader) { described_class.new(cookbooks_to_upload, :rest => http_client) }
+ let(:policy_mode) { false }
+
+ let(:uploader) { described_class.new(cookbooks_to_upload, rest: http_client, policy_mode: policy_mode) }
+
+ it "defaults to not enabling policy mode" do
+ expect(described_class.new(cookbooks_to_upload, rest: http_client).policy_mode?).to be(false)
+ end
it "has a list of cookbooks to upload" do
expect(uploader.cookbooks).to eq(cookbooks_to_upload)
@@ -61,7 +67,7 @@ describe Chef::CookbookUploader do
describe "uploading cookbooks" do
def url_for(cksum)
- "https://storage.example.com/#{cksum}"
+ "https://storage.example.com/#{cksum}"
end
let(:sandbox_response) do
@@ -94,6 +100,10 @@ describe Chef::CookbookUploader do
end
end
+ def expected_save_url(cookbook)
+ "cookbooks/#{cookbook.name}/#{cookbook.version}"
+ end
+
def expect_sandbox_commit
expect(http_client).to receive(:put).with(sandbox_commit_uri, {:is_completed => true})
end
@@ -102,7 +112,7 @@ describe Chef::CookbookUploader do
cookbooks_to_upload.each do |cookbook|
expect(http_client).to receive(:put).
- with(cookbook.save_url, cookbook)
+ with(expected_save_url(cookbook), cookbook)
end
end
@@ -155,6 +165,30 @@ describe Chef::CookbookUploader do
end
end
+
+ context "when policy_mode is specified" do
+
+ let(:cksums_not_on_remote) do
+ checksums_of_cookbook_files.keys
+ end
+
+ let(:policy_mode) { true }
+
+ def expected_save_url(cookbook)
+ "cookbook_artifacts/#{cookbook.name}/#{cookbook.version}"
+ end
+
+ it "uploads all files in a sandbox transaction, then creates cookbooks on the server using cookbook_artifacts API" do
+ expect_sandbox_create
+ expect_checksum_upload
+ expect_sandbox_commit
+ expect_cookbook_create
+
+ uploader.upload_cookbooks
+ end
+
+
+ end
end
end
diff --git a/spec/unit/cookbook_version_file_specificity_spec.rb b/spec/unit/cookbook_version_file_specificity_spec.rb
new file mode 100644
index 0000000000..73b10899d4
--- /dev/null
+++ b/spec/unit/cookbook_version_file_specificity_spec.rb
@@ -0,0 +1,554 @@
+#
+# Author:: Tim Hinderliter (<tim@opscode.com>)
+# Author:: Christopher Walters (<cw@opscode.com>)
+# Copyright:: Copyright (c) 2010 Opscode, 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::CookbookVersion, "file specificity" do
+ before(:each) do
+ @cookbook = Chef::CookbookVersion.new "test-cookbook"
+ @cookbook.manifest = {
+ "files" =>
+ [
+ # afile.rb
+ {
+ :name => "afile.rb",
+ :path => "files/host-examplehost.example.org/afile.rb",
+ :checksum => "csum-host",
+ :specificity => "host-examplehost.example.org"
+ },
+ {
+ :name => "afile.rb",
+ :path => "files/ubuntu-9.10/afile.rb",
+ :checksum => "csum-platver-full",
+ :specificity => "ubuntu-9.10"
+ },
+ {
+ :name => "afile.rb",
+ :path => "files/newubuntu-9/afile.rb",
+ :checksum => "csum-platver-partial",
+ :specificity => "newubuntu-9"
+ },
+ {
+ :name => "afile.rb",
+ :path => "files/ubuntu/afile.rb",
+ :checksum => "csum-plat",
+ :specificity => "ubuntu"
+ },
+ {
+ :name => "afile.rb",
+ :path => "files/default/afile.rb",
+ :checksum => "csum-default",
+ :specificity => "default"
+ },
+
+ # for different/odd platform_versions
+ {
+ :name => "bfile.rb",
+ :path => "files/fakeos-2.0.rc.1/bfile.rb",
+ :checksum => "csum2-platver-full",
+ :specificity => "fakeos-2.0.rc.1"
+ },
+ {
+ :name => "bfile.rb",
+ :path => "files/newfakeos-2.0.rc/bfile.rb",
+ :checksum => "csum2-platver-partial",
+ :specificity => "newfakeos-2.0.rc"
+ },
+ {
+ :name => "bfile.rb",
+ :path => "files/fakeos-maple tree/bfile.rb",
+ :checksum => "csum3-platver-full",
+ :specificity => "maple tree"
+ },
+ {
+ :name => "bfile.rb",
+ :path => "files/fakeos-1/bfile.rb",
+ :checksum => "csum4-platver-full",
+ :specificity => "fakeos-1"
+ },
+
+ # directory adirectory
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/host-examplehost.example.org/adirectory/anotherfile1.rb.host",
+ :checksum => "csum-host-1",
+ :specificity => "host-examplehost.example.org"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/host-examplehost.example.org/adirectory/anotherfile2.rb.host",
+ :checksum => "csum-host-2",
+ :specificity => "host-examplehost.example.org"
+ },
+
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/ubuntu-9.10/adirectory/anotherfile1.rb.platform-full-version",
+ :checksum => "csum-platver-full-1",
+ :specificity => "ubuntu-9.10"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/ubuntu-9.10/adirectory/anotherfile2.rb.platform-full-version",
+ :checksum => "csum-platver-full-2",
+ :specificity => "ubuntu-9.10"
+ },
+
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/newubuntu-9/adirectory/anotherfile1.rb.platform-partial-version",
+ :checksum => "csum-platver-partial-1",
+ :specificity => "newubuntu-9"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/newubuntu-9/adirectory/anotherfile2.rb.platform-partial-version",
+ :checksum => "csum-platver-partial-2",
+ :specificity => "nweubuntu-9"
+ },
+
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/ubuntu/adirectory/anotherfile1.rb.platform",
+ :checksum => "csum-plat-1",
+ :specificity => "ubuntu"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/ubuntu/adirectory/anotherfile2.rb.platform",
+ :checksum => "csum-plat-2",
+ :specificity => "ubuntu"
+ },
+
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/default/adirectory/anotherfile1.rb.default",
+ :checksum => "csum-default-1",
+ :specificity => "default"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/default/adirectory/anotherfile2.rb.default",
+ :checksum => "csum-default-2",
+ :specificity => "default"
+ },
+ # for different/odd platform_versions
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/fakeos-2.0.rc.1/adirectory/anotherfile1.rb.platform-full-version",
+ :checksum => "csum2-platver-full-1",
+ :specificity => "fakeos-2.0.rc.1"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/fakeos-2.0.rc.1/adirectory/anotherfile2.rb.platform-full-version",
+ :checksum => "csum2-platver-full-2",
+ :specificity => "fakeos-2.0.rc.1"
+ },
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/newfakeos-2.0.rc.1/adirectory/anotherfile1.rb.platform-partial-version",
+ :checksum => "csum2-platver-partial-1",
+ :specificity => "newfakeos-2.0.rc"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/newfakeos-2.0.rc.1/adirectory/anotherfile2.rb.platform-partial-version",
+ :checksum => "csum2-platver-partial-2",
+ :specificity => "newfakeos-2.0.rc"
+ },
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/fakeos-maple tree/adirectory/anotherfile1.rb.platform-full-version",
+ :checksum => "csum3-platver-full-1",
+ :specificity => "fakeos-maple tree"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/fakeos-maple tree/adirectory/anotherfile2.rb.platform-full-version",
+ :checksum => "csum3-platver-full-2",
+ :specificity => "fakeos-maple tree"
+ },
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/fakeos-1/adirectory/anotherfile1.rb.platform-full-version",
+ :checksum => "csum4-platver-full-1",
+ :specificity => "fakeos-1"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/fakeos-1/adirectory/anotherfile2.rb.platform-full-version",
+ :checksum => "csum4-platver-full-2",
+ :specificity => "fakeos-1"
+ },
+ ]
+ }
+
+ end
+
+
+ it "should return a manifest record based on priority preference: host" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "examplehost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum-host")
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum-platver-full")
+ end
+
+ it "should return a manifest record based on priority preference: platform & partial version" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "newubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum-platver-partial")
+ end
+
+ it "should return a manifest record based on priority preference: platform only" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "1.0"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum-plat")
+ end
+
+ it "should return a manifest record based on priority preference: default" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "notubuntu"
+ node.automatic_attrs[:platform_version] = "1.0"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum-default")
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version - platform_version variant 1" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "2.0.rc.1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum2-platver-full")
+ end
+
+ it "should return a manifest record based on priority preference: platform & partial version - platform_version variant 1" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "newfakeos"
+ node.automatic_attrs[:platform_version] = "2.0.rc.1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum2-platver-partial")
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version - platform_version variant 2" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "maple tree"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum3-platver-full")
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version - platform_version variant 3" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum4-platver-full")
+ end
+
+ describe "when fetching the contents of a directory by file specificity" do
+
+ it "should return a directory of manifest records based on priority preference: host" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "examplehost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum-host-1", "csum-host-2"])
+ end
+
+ it "should return a directory of manifest records based on priority preference: platform & full version" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum-platver-full-1", "csum-platver-full-2"])
+ end
+
+ it "should return a directory of manifest records based on priority preference: platform & partial version" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "newubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum-platver-partial-1", "csum-platver-partial-2"])
+ end
+
+ it "should return a directory of manifest records based on priority preference: platform only" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "1.0"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum-plat-1", "csum-plat-2"])
+ end
+
+ it "should return a directory of manifest records based on priority preference: default" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "notubuntu"
+ node.automatic_attrs[:platform_version] = "1.0"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum-default-1", "csum-default-2"])
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version - platform_version variant 1" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "2.0.rc.1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum2-platver-full-1", "csum2-platver-full-2"])
+ end
+
+ it "should return a manifest record based on priority preference: platform & partial version - platform_version variant 1" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "newfakeos"
+ node.automatic_attrs[:platform_version] = "2.0.rc.1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum2-platver-partial-1", "csum2-platver-partial-2"])
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version - platform_version variant 2" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "maple tree"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum3-platver-full-1", "csum3-platver-full-2"])
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version - platform_version variant 3" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum4-platver-full-1", "csum4-platver-full-2"])
+ end
+ end
+
+ ## Globbing the relative paths out of the manifest records ##
+
+ describe "when globbing for relative file paths based on filespecificity" do
+ it "should return a list of relative paths based on priority preference: host" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "examplehost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.host', 'anotherfile2.rb.host'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform & full version" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform & partial version" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "newubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform-partial-version', 'anotherfile2.rb.platform-partial-version'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform only" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "1.0"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform', 'anotherfile2.rb.platform'])
+ end
+
+ it "should return a list of relative paths based on priority preference: default" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "notubuntu"
+ node.automatic_attrs[:platform_version] = "1.0"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.default', 'anotherfile2.rb.default'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform & full version - platform_version variant 1" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "2.0.rc.1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform & partial version - platform_version variant 1" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "newfakeos"
+ node.automatic_attrs[:platform_version] = "2.0.rc.1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform-partial-version', 'anotherfile2.rb.platform-partial-version'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform & full version - platform_version variant 2" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "maple tree"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform & full version - platform_version variant 3" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version'])
+ end
+ end
+end
diff --git a/spec/unit/cookbook_version_spec.rb b/spec/unit/cookbook_version_spec.rb
index 6dd3429ffc..440dd9da6c 100644
--- a/spec/unit/cookbook_version_spec.rb
+++ b/spec/unit/cookbook_version_spec.rb
@@ -68,32 +68,10 @@ describe Chef::CookbookVersion do
expect(@cookbook_version).to be_frozen_version
end
- it "is \"ready\"" do
- # WTF is this? what are the valid states? and why aren't they set with encapsulating methods?
- # [Dan 15-Jul-2010]
- expect(@cookbook_version.status).to eq(:ready)
- end
-
it "has empty metadata" do
expect(@cookbook_version.metadata).to eq(Chef::Cookbook::Metadata.new)
end
- it "creates a manifest hash of its contents" do
- expected = {"recipes"=>[],
- "definitions"=>[],
- "libraries"=>[],
- "attributes"=>[],
- "files"=>[],
- "templates"=>[],
- "resources"=>[],
- "providers"=>[],
- "root_files"=>[],
- "cookbook_name"=>"tatft",
- "metadata"=>Chef::Cookbook::Metadata.new,
- "version"=>"0.0.0",
- "name"=>"tatft-0.0.0"}
- expect(@cookbook_version.manifest).to eq(expected)
- end
end
describe "with a cookbook directory named tatft" do
@@ -141,85 +119,6 @@ describe Chef::CookbookVersion do
@node.name("testing")
end
- it "generates a manifest containing the cookbook's files" do
- manifest = @cookbook_version.manifest
-
- expect(manifest["metadata"]).to eq(Chef::Cookbook::Metadata.new)
- expect(manifest["cookbook_name"]).to eq("tatft")
-
- expect(manifest["recipes"].size).to eq(1)
-
- recipe = manifest["recipes"].first
- expect(recipe["name"]).to eq("default.rb")
- expect(recipe["path"]).to eq("recipes/default.rb")
- expect(recipe["checksum"]).to match(MD5)
- expect(recipe["specificity"]).to eq("default")
-
- expect(manifest["definitions"].size).to eq(1)
-
- definition = manifest["definitions"].first
- expect(definition["name"]).to eq("runit_service.rb")
- expect(definition["path"]).to eq("definitions/runit_service.rb")
- expect(definition["checksum"]).to match(MD5)
- expect(definition["specificity"]).to eq("default")
-
- expect(manifest["libraries"].size).to eq(1)
-
- library = manifest["libraries"].first
- expect(library["name"]).to eq("ownage.rb")
- expect(library["path"]).to eq("libraries/ownage.rb")
- expect(library["checksum"]).to match(MD5)
- expect(library["specificity"]).to eq("default")
-
- expect(manifest["attributes"].size).to eq(1)
-
- attribute_file = manifest["attributes"].first
- expect(attribute_file["name"]).to eq("default.rb")
- expect(attribute_file["path"]).to eq("attributes/default.rb")
- expect(attribute_file["checksum"]).to match(MD5)
- expect(attribute_file["specificity"]).to eq("default")
-
- expect(manifest["files"].size).to eq(1)
-
- cookbook_file = manifest["files"].first
- expect(cookbook_file["name"]).to eq("giant_blob.tgz")
- expect(cookbook_file["path"]).to eq("files/default/giant_blob.tgz")
- expect(cookbook_file["checksum"]).to match(MD5)
- expect(cookbook_file["specificity"]).to eq("default")
-
- expect(manifest["templates"].size).to eq(1)
-
- template = manifest["templates"].first
- expect(template["name"]).to eq("configuration.erb")
- expect(template["path"]).to eq("templates/default/configuration.erb")
- expect(template["checksum"]).to match(MD5)
- expect(template["specificity"]).to eq("default")
-
- expect(manifest["resources"].size).to eq(1)
-
- lwr = manifest["resources"].first
- expect(lwr["name"]).to eq("lwr.rb")
- expect(lwr["path"]).to eq("resources/lwr.rb")
- expect(lwr["checksum"]).to match(MD5)
- expect(lwr["specificity"]).to eq("default")
-
- expect(manifest["providers"].size).to eq(1)
-
- lwp = manifest["providers"].first
- expect(lwp["name"]).to eq("lwp.rb")
- expect(lwp["path"]).to eq("providers/lwp.rb")
- expect(lwp["checksum"]).to match(MD5)
- expect(lwp["specificity"]).to eq("default")
-
- expect(manifest["root_files"].size).to eq(1)
-
- readme = manifest["root_files"].first
- expect(readme["name"]).to eq("README.rdoc")
- expect(readme["path"]).to eq("README.rdoc")
- expect(readme["checksum"]).to match(MD5)
- expect(readme["specificity"]).to eq("default")
- end
-
it "determines whether a template is available for a given node" do
expect(@cookbook_version).to have_template_for_node(@node, "configuration.erb")
expect(@cookbook_version).not_to have_template_for_node(@node, "missing.erb")
@@ -253,102 +152,6 @@ describe Chef::CookbookVersion do
end
end
- describe "and a cookbook_version with a different name" do
- before do
- # Currently the cookbook loader finds all the files then tells CookbookVersion
- # where they are.
- @cookbook_version = Chef::CookbookVersion.new("blarghle", @cookbook_root)
- @cookbook_version.attribute_filenames = @cookbook[:attribute_filenames]
- @cookbook_version.definition_filenames = @cookbook[:definition_filenames]
- @cookbook_version.recipe_filenames = @cookbook[:recipe_filenames]
- @cookbook_version.template_filenames = @cookbook[:template_filenames]
- @cookbook_version.file_filenames = @cookbook[:file_filenames]
- @cookbook_version.library_filenames = @cookbook[:library_filenames]
- @cookbook_version.resource_filenames = @cookbook[:resource_filenames]
- @cookbook_version.provider_filenames = @cookbook[:provider_filenames]
- @cookbook_version.root_filenames = @cookbook[:root_filenames]
- @cookbook_version.metadata_filenames = @cookbook[:metadata_filenames]
- end
-
- it "generates a manifest containing the cookbook's files" do
- manifest = @cookbook_version.manifest
-
- expect(manifest["metadata"]).to eq(Chef::Cookbook::Metadata.new)
- expect(manifest["cookbook_name"]).to eq("blarghle")
-
- expect(manifest["recipes"].size).to eq(1)
-
- recipe = manifest["recipes"].first
- expect(recipe["name"]).to eq("default.rb")
- expect(recipe["path"]).to eq("recipes/default.rb")
- expect(recipe["checksum"]).to match(MD5)
- expect(recipe["specificity"]).to eq("default")
-
- expect(manifest["definitions"].size).to eq(1)
-
- definition = manifest["definitions"].first
- expect(definition["name"]).to eq("runit_service.rb")
- expect(definition["path"]).to eq("definitions/runit_service.rb")
- expect(definition["checksum"]).to match(MD5)
- expect(definition["specificity"]).to eq("default")
-
- expect(manifest["libraries"].size).to eq(1)
-
- library = manifest["libraries"].first
- expect(library["name"]).to eq("ownage.rb")
- expect(library["path"]).to eq("libraries/ownage.rb")
- expect(library["checksum"]).to match(MD5)
- expect(library["specificity"]).to eq("default")
-
- expect(manifest["attributes"].size).to eq(1)
-
- attribute_file = manifest["attributes"].first
- expect(attribute_file["name"]).to eq("default.rb")
- expect(attribute_file["path"]).to eq("attributes/default.rb")
- expect(attribute_file["checksum"]).to match(MD5)
- expect(attribute_file["specificity"]).to eq("default")
-
- expect(manifest["files"].size).to eq(1)
-
- cookbook_file = manifest["files"].first
- expect(cookbook_file["name"]).to eq("giant_blob.tgz")
- expect(cookbook_file["path"]).to eq("files/default/giant_blob.tgz")
- expect(cookbook_file["checksum"]).to match(MD5)
- expect(cookbook_file["specificity"]).to eq("default")
-
- expect(manifest["templates"].size).to eq(1)
-
- template = manifest["templates"].first
- expect(template["name"]).to eq("configuration.erb")
- expect(template["path"]).to eq("templates/default/configuration.erb")
- expect(template["checksum"]).to match(MD5)
- expect(template["specificity"]).to eq("default")
-
- expect(manifest["resources"].size).to eq(1)
-
- lwr = manifest["resources"].first
- expect(lwr["name"]).to eq("lwr.rb")
- expect(lwr["path"]).to eq("resources/lwr.rb")
- expect(lwr["checksum"]).to match(MD5)
- expect(lwr["specificity"]).to eq("default")
-
- expect(manifest["providers"].size).to eq(1)
-
- lwp = manifest["providers"].first
- expect(lwp["name"]).to eq("lwp.rb")
- expect(lwp["path"]).to eq("providers/lwp.rb")
- expect(lwp["checksum"]).to match(MD5)
- expect(lwp["specificity"]).to eq("default")
-
- expect(manifest["root_files"].size).to eq(1)
-
- readme = manifest["root_files"].first
- expect(readme["name"]).to eq("README.rdoc")
- expect(readme["path"]).to eq("README.rdoc")
- expect(readme["checksum"]).to match(MD5)
- expect(readme["specificity"]).to eq("default")
- end
- end
end
describe 'with a cookbook directory named cookbook2 that has unscoped files' do
@@ -499,8 +302,63 @@ describe Chef::CookbookVersion do
end
- include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
- let(:jsonable) { Chef::CookbookVersion.new("tatft", '/tmp/blah') }
+ describe "when deprecation warnings are errors" do
+
+ subject(:cbv) { Chef::CookbookVersion.new("version validation", '/tmp/blah') }
+
+ describe "HTTP Resource behaviors", pending: "will be deprected when CookbookManifest API is stablized" do
+
+ it "errors on #save_url" do
+ expect { cbv.save_url }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
+ end
+
+ it "errors on #force_save_url" do
+ expect { cbv.force_save_url }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
+ end
+
+ it "errors on #to_hash" do
+ expect { cbv.to_hash }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
+ end
+
+ it "errors on #to_json" do
+ expect { cbv.to_json }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
+ end
+
+ end
+
+ it "errors on #status and #status=" do
+ expect { cbv.status = :wat }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
+ expect { cbv.status }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
+ end
+
end
+ describe "deprecated features" do
+
+ subject(:cbv) { Chef::CookbookVersion.new("tatft", '/tmp/blah').tap { |c| c.version = "1.2.3" } }
+
+ before do
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
+ end
+
+ it "gives a save URL for the standard cookbook API" do
+ expect(cbv.save_url).to eq("cookbooks/tatft/1.2.3")
+ end
+
+ it "gives a force save URL for the standard cookbook API" do
+ expect(cbv.force_save_url).to eq("cookbooks/tatft/1.2.3?force=true")
+ end
+
+ it "is \"ready\"" do
+ # WTF is this? what are the valid states? and why aren't they set with encapsulating methods?
+ # [Dan 15-Jul-2010]
+ expect(cbv.status).to eq(:ready)
+ end
+
+
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:jsonable) { Chef::CookbookVersion.new("tatft", '/tmp/blah') }
+ end
+
+ end
end
diff --git a/spec/unit/data_bag_item_spec.rb b/spec/unit/data_bag_item_spec.rb
index 4cf6e59242..4348252388 100644
--- a/spec/unit/data_bag_item_spec.rb
+++ b/spec/unit/data_bag_item_spec.rb
@@ -20,86 +20,86 @@ require 'spec_helper'
require 'chef/data_bag_item'
describe Chef::DataBagItem do
- before(:each) do
- @data_bag_item = Chef::DataBagItem.new
- end
+ let(:data_bag_item) { Chef::DataBagItem.new }
describe "initialize" do
it "should be a Chef::DataBagItem" do
- expect(@data_bag_item).to be_a_kind_of(Chef::DataBagItem)
+ expect(data_bag_item).to be_a_kind_of(Chef::DataBagItem)
end
end
describe "data_bag" do
it "should let you set the data_bag to a string" do
- expect(@data_bag_item.data_bag("clowns")).to eq("clowns")
+ expect(data_bag_item.data_bag("clowns")).to eq("clowns")
end
it "should return the current data_bag type" do
- @data_bag_item.data_bag "clowns"
- expect(@data_bag_item.data_bag).to eq("clowns")
+ data_bag_item.data_bag "clowns"
+ expect(data_bag_item.data_bag).to eq("clowns")
end
it "should not accept spaces" do
- expect { @data_bag_item.data_bag "clown masters" }.to raise_error(ArgumentError)
+ expect { data_bag_item.data_bag "clown masters" }.to raise_error(ArgumentError)
end
it "should throw an ArgumentError if you feed it anything but a string" do
- expect { @data_bag_item.data_bag Hash.new }.to raise_error(ArgumentError)
+ expect { data_bag_item.data_bag Hash.new }.to raise_error(ArgumentError)
end
end
describe "raw_data" do
it "should let you set the raw_data with a hash" do
- expect { @data_bag_item.raw_data = { "id" => "octahedron" } }.not_to raise_error
+ expect { data_bag_item.raw_data = { "id" => "octahedron" } }.not_to raise_error
end
it "should let you set the raw_data from a mash" do
- expect { @data_bag_item.raw_data = Mash.new({ "id" => "octahedron" }) }.not_to raise_error
+ expect { data_bag_item.raw_data = Mash.new({ "id" => "octahedron" }) }.not_to raise_error
end
it "should raise an exception if you set the raw data without a key" do
- expect { @data_bag_item.raw_data = { "monkey" => "pants" } }.to raise_error(ArgumentError)
+ expect { data_bag_item.raw_data = { "monkey" => "pants" } }.to raise_error(ArgumentError)
end
it "should raise an exception if you set the raw data to something other than a hash" do
- expect { @data_bag_item.raw_data = "katie rules" }.to raise_error(ArgumentError)
+ expect { data_bag_item.raw_data = "katie rules" }.to raise_error(ArgumentError)
end
it "should accept alphanum/-/_ for the id" do
- expect { @data_bag_item.raw_data = { "id" => "h1-_" } }.not_to raise_error
+ expect { data_bag_item.raw_data = { "id" => "h1-_" } }.not_to raise_error
end
it "should accept alphanum.alphanum for the id" do
- expect { @data_bag_item.raw_data = { "id" => "foo.bar" } }.not_to raise_error
+ expect { data_bag_item.raw_data = { "id" => "foo.bar" } }.not_to raise_error
end
it "should accept .alphanum for the id" do
- expect { @data_bag_item.raw_data = { "id" => ".bozo" } }.not_to raise_error
+ expect { data_bag_item.raw_data = { "id" => ".bozo" } }.not_to raise_error
end
it "should raise an exception if the id contains anything but alphanum/-/_" do
- expect { @data_bag_item.raw_data = { "id" => "!@#" } }.to raise_error(ArgumentError)
+ expect { data_bag_item.raw_data = { "id" => "!@#" } }.to raise_error(ArgumentError)
end
it "should return the raw data" do
- @data_bag_item.raw_data = { "id" => "highway_of_emptiness" }
- expect(@data_bag_item.raw_data).to eq({ "id" => "highway_of_emptiness" })
+ data_bag_item.raw_data = { "id" => "highway_of_emptiness" }
+ expect(data_bag_item.raw_data).to eq({ "id" => "highway_of_emptiness" })
end
it "should be a Mash by default" do
- expect(@data_bag_item.raw_data).to be_a_kind_of(Mash)
+ expect(data_bag_item.raw_data).to be_a_kind_of(Mash)
end
end
describe "object_name" do
- before(:each) do
- @data_bag_item.data_bag("dreams")
- @data_bag_item.raw_data = { "id" => "the_beatdown" }
- end
+ let(:data_bag_item) {
+ data_bag_item = Chef::DataBagItem.new
+ data_bag_item.data_bag("dreams")
+ data_bag_item.raw_data = { "id" => "the_beatdown" }
+ data_bag_item
+ }
it "should return an object name based on the bag name and the raw_data id" do
- expect(@data_bag_item.object_name).to eq("data_bag_item_dreams_the_beatdown")
+ expect(data_bag_item.object_name).to eq("data_bag_item_dreams_the_beatdown")
end
end
@@ -110,17 +110,19 @@ describe Chef::DataBagItem do
end
describe "when used like a Hash" do
- before(:each) do
- @data_bag_item.raw_data = { "id" => "journey", "trials" => "been through" }
- end
+ let(:data_bag_item) {
+ data_bag_item = Chef::DataBagItem.new
+ data_bag_item.raw_data = { "id" => "journey", "trials" => "been through" }
+ data_bag_item
+ }
it "responds to keys" do
- expect(@data_bag_item.keys).to include("id")
- expect(@data_bag_item.keys).to include("trials")
+ expect(data_bag_item.keys).to include("id")
+ expect(data_bag_item.keys).to include("trials")
end
it "supports element reference with []" do
- expect(@data_bag_item["id"]).to eq("journey")
+ expect(data_bag_item["id"]).to eq("journey")
end
it "implements all the methods of Hash" do
@@ -131,100 +133,113 @@ describe Chef::DataBagItem do
:invert, :update, :replace, :merge!, :merge, :has_key?, :has_value?,
:key?, :value?]
methods.each do |m|
- expect(@data_bag_item).to respond_to(m)
+ expect(data_bag_item).to respond_to(m)
end
end
-
end
describe "to_hash" do
- before(:each) do
- @data_bag_item.data_bag("still_lost")
- @data_bag_item.raw_data = { "id" => "whoa", "i_know" => "kung_fu" }
- @to_hash = @data_bag_item.to_hash
- end
+ let(:data_bag_item) {
+ data_bag_item = Chef::DataBagItem.new
+ data_bag_item.data_bag("still_lost")
+ data_bag_item.raw_data = { "id" => "whoa", "i_know" => "kung_fu" }
+ data_bag_item
+ }
+
+ let(:to_hash) { data_bag_item.to_hash }
it "should return a hash" do
- expect(@to_hash).to be_a_kind_of(Hash)
+ expect(to_hash).to be_a_kind_of(Hash)
end
it "should have the raw_data keys as top level keys" do
- expect(@to_hash["id"]).to eq("whoa")
- expect(@to_hash["i_know"]).to eq("kung_fu")
+ expect(to_hash["id"]).to eq("whoa")
+ expect(to_hash["i_know"]).to eq("kung_fu")
end
it "should have the chef_type of data_bag_item" do
- expect(@to_hash["chef_type"]).to eq("data_bag_item")
+ expect(to_hash["chef_type"]).to eq("data_bag_item")
end
it "should have the data_bag set" do
- expect(@to_hash["data_bag"]).to eq("still_lost")
+ expect(to_hash["data_bag"]).to eq("still_lost")
end
end
describe "when deserializing from JSON" do
- before(:each) do
- @data_bag_item.data_bag('mars_volta')
- @data_bag_item.raw_data = { "id" => "octahedron", "snooze" => { "finally" => :world_will }}
- @deserial = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(@data_bag_item))
- end
+ let(:data_bag_item) {
+ data_bag_item = Chef::DataBagItem.new
+ data_bag_item.data_bag('mars_volta')
+ data_bag_item.raw_data = { "id" => "octahedron", "snooze" => { "finally" => :world_will } }
+ data_bag_item
+ }
+
+ let(:deserial) { Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(data_bag_item)) }
+
it "should deserialize to a Chef::DataBagItem object" do
- expect(@deserial).to be_a_kind_of(Chef::DataBagItem)
+ expect(deserial).to be_a_kind_of(Chef::DataBagItem)
end
it "should have a matching 'data_bag' value" do
- expect(@deserial.data_bag).to eq(@data_bag_item.data_bag)
+ expect(deserial.data_bag).to eq(data_bag_item.data_bag)
end
it "should have a matching 'id' key" do
- expect(@deserial["id"]).to eq("octahedron")
+ expect(deserial["id"]).to eq("octahedron")
end
it "should have a matching 'snooze' key" do
- expect(@deserial["snooze"]).to eq({ "finally" => "world_will" })
+ expect(deserial["snooze"]).to eq({ "finally" => "world_will" })
end
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
- let(:jsonable) { @data_bag_item }
+ let(:jsonable) { data_bag_item }
end
end
describe "when converting to a string" do
it "converts to a string in the form data_bag_item[ID]" do
- @data_bag_item['id'] = "heart of darkness"
- expect(@data_bag_item.to_s).to eq('data_bag_item[heart of darkness]')
+ data_bag_item['id'] = "heart of darkness"
+ expect(data_bag_item.to_s).to eq('data_bag_item[heart of darkness]')
end
it "inspects as data_bag_item[BAG, ID, RAW_DATA]" do
raw_data = {"id" => "heart_of_darkness", "author" => "Conrad"}
- @data_bag_item.raw_data = raw_data
- @data_bag_item.data_bag("books")
+ data_bag_item.raw_data = raw_data
+ data_bag_item.data_bag("books")
- expect(@data_bag_item.inspect).to eq("data_bag_item[\"books\", \"heart_of_darkness\", #{raw_data.inspect}]")
+ expect(data_bag_item.inspect).to eq("data_bag_item[\"books\", \"heart_of_darkness\", #{raw_data.inspect}]")
end
end
describe "save" do
+ let(:server) { instance_double(Chef::REST) }
+
+ let(:data_bag_item) {
+ data_bag_item = Chef::DataBagItem.new
+ data_bag_item['id'] = "heart of darkness"
+ data_bag_item.raw_data = {"id" => "heart_of_darkness", "author" => "Conrad"}
+ data_bag_item.data_bag("books")
+ data_bag_item
+ }
+
before do
- @rest = double("Chef::REST")
- allow(Chef::REST).to receive(:new).and_return(@rest)
- @data_bag_item['id'] = "heart of darkness"
- raw_data = {"id" => "heart_of_darkness", "author" => "Conrad"}
- @data_bag_item.raw_data = raw_data
- @data_bag_item.data_bag("books")
+ expect(Chef::REST).to receive(:new).and_return(server)
end
+
it "should update the item when it already exists" do
- expect(@rest).to receive(:put_rest).with("data/books/heart_of_darkness", @data_bag_item)
- @data_bag_item.save
+ expect(server).to receive(:put_rest).with("data/books/heart_of_darkness", data_bag_item)
+ data_bag_item.save
end
it "should create if the item is not found" do
exception = double("404 error", :code => "404")
- expect(@rest).to receive(:put_rest).and_raise(Net::HTTPServerException.new("foo", exception))
- expect(@rest).to receive(:post_rest).with("data/books", @data_bag_item)
- @data_bag_item.save
+ expect(server).to receive(:put_rest).and_raise(Net::HTTPServerException.new("foo", exception))
+ expect(server).to receive(:post_rest).with("data/books", data_bag_item)
+ data_bag_item.save
end
+
describe "when whyrun mode is enabled" do
before do
Chef::Config[:why_run] = true
@@ -232,41 +247,60 @@ describe Chef::DataBagItem do
after do
Chef::Config[:why_run] = false
end
+
it "should not save" do
- expect(@rest).not_to receive(:put_rest)
- expect(@rest).not_to receive(:post_rest)
- @data_bag_item.data_bag("books")
- @data_bag_item.save
+ expect(server).not_to receive(:put_rest)
+ expect(server).not_to receive(:post_rest)
+ data_bag_item.data_bag("books")
+ data_bag_item.save
end
end
+ end
+
+ describe "destroy" do
+ let(:server) { instance_double(Chef::REST) }
+
+ let(:data_bag_item) {
+ data_bag_item = Chef::DataBagItem.new
+ data_bag_item.data_bag('a_baggy_bag')
+ data_bag_item.raw_data = { "id" => "some_id" }
+ data_bag_item
+ }
+ it "should set default parameters" do
+ expect(Chef::REST).to receive(:new).and_return(server)
+ expect(server).to receive(:delete_rest).with("data/a_baggy_bag/data_bag_item_a_baggy_bag_some_id")
+
+ data_bag_item.destroy
+ end
end
describe "when loading" do
before do
- @data_bag_item.raw_data = {"id" => "charlie", "shell" => "zsh", "ssh_keys" => %w{key1 key2}}
- @data_bag_item.data_bag("users")
+ data_bag_item.raw_data = {"id" => "charlie", "shell" => "zsh", "ssh_keys" => %w{key1 key2}}
+ data_bag_item.data_bag("users")
end
describe "from an API call" do
+ let(:http_client) { double("Chef::REST") }
+
before do
- @http_client = double("Chef::REST")
- allow(Chef::REST).to receive(:new).and_return(@http_client)
+ allow(Chef::REST).to receive(:new).and_return(http_client)
end
it "converts raw data to a data bag item" do
- expect(@http_client).to receive(:get_rest).with("data/users/charlie").and_return(@data_bag_item.to_hash)
+ expect(http_client).to receive(:get_rest).with("data/users/charlie").and_return(data_bag_item.to_hash)
item = Chef::DataBagItem.load(:users, "charlie")
expect(item).to be_a_kind_of(Chef::DataBagItem)
- expect(item).to eq(@data_bag_item)
+ expect(item).to eq(data_bag_item)
end
it "does not convert when a DataBagItem is returned from the API call" do
- expect(@http_client).to receive(:get_rest).with("data/users/charlie").and_return(@data_bag_item)
+ expect(http_client).to receive(:get_rest).with("data/users/charlie").and_return(data_bag_item)
item = Chef::DataBagItem.load(:users, "charlie")
expect(item).to be_a_kind_of(Chef::DataBagItem)
- expect(item).to equal(@data_bag_item)
+ expect(item).to equal(data_bag_item)
end
end
@@ -280,13 +314,11 @@ describe Chef::DataBagItem do
end
it "converts the raw data to a data bag item" do
- expect(Chef::DataBag).to receive(:load).with('users').and_return({'charlie' => @data_bag_item.to_hash})
+ expect(Chef::DataBag).to receive(:load).with('users').and_return({'charlie' => data_bag_item.to_hash})
item = Chef::DataBagItem.load('users', 'charlie')
expect(item).to be_a_kind_of(Chef::DataBagItem)
- expect(item).to eq(@data_bag_item)
+ expect(item).to eq(data_bag_item)
end
end
-
end
-
end
diff --git a/spec/unit/deprecation_spec.rb b/spec/unit/deprecation_spec.rb
index 9bd081a6c4..f824cb7c76 100644
--- a/spec/unit/deprecation_spec.rb
+++ b/spec/unit/deprecation_spec.rb
@@ -59,27 +59,40 @@ describe Chef::Deprecation do
end
end
- context 'deprecation warning messages' do
- before(:each) do
- @warning_output = [ ]
- allow(Chef::Log).to receive(:warn) { |msg| @warning_output << msg }
+ context 'when Chef::Config[:treat_deprecation_warnings_as_errors] is off' do
+ before do
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
end
- it 'should be enabled for deprecated methods' do
- TestClass.new.deprecated_method(10)
- expect(@warning_output).not_to be_empty
+ context 'deprecation warning messages' do
+ before(:each) do
+ @warning_output = [ ]
+ allow(Chef::Log).to receive(:warn) { |msg| @warning_output << msg }
+ end
+
+ it 'should be enabled for deprecated methods' do
+ TestClass.new.deprecated_method(10)
+ expect(@warning_output).not_to be_empty
+ end
+
+ it 'should contain stack trace' do
+ TestClass.new.deprecated_method(10)
+ expect(@warning_output.join("").include?(".rb")).to be_truthy
+ end
end
- it 'should contain stack trace' do
- TestClass.new.deprecated_method(10)
- expect(@warning_output.join("").include?(".rb")).to be_truthy
+ it 'deprecated methods should still be called' do
+ test_instance = TestClass.new
+ test_instance.deprecated_method(10)
+ expect(test_instance.get_value).to eq(10)
end
end
- it 'deprecated methods should still be called' do
+ it 'should raise when deprecation warnings are treated as errors' do
+ # rspec should set this
+ expect(Chef::Config[:treat_deprecation_warnings_as_errors]).to be true
test_instance = TestClass.new
- test_instance.deprecated_method(10)
- expect(test_instance.get_value).to eq(10)
+ expect { test_instance.deprecated_method(10) }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
end
end
diff --git a/spec/unit/dsl/audit_spec.rb b/spec/unit/dsl/audit_spec.rb
index 38707127f0..28b28e0a7c 100644
--- a/spec/unit/dsl/audit_spec.rb
+++ b/spec/unit/dsl/audit_spec.rb
@@ -17,18 +17,18 @@ describe Chef::DSL::Audit do
let(:cookbook_collection) { {} }
it "raises an error when a block of audits is not provided" do
- expect{ auditor.controls "name" }.to raise_error(Chef::Exceptions::NoAuditsProvided)
+ expect{ auditor.control_group "name" }.to raise_error(Chef::Exceptions::NoAuditsProvided)
end
it "raises an error when no audit name is given" do
- expect{ auditor.controls do end }.to raise_error(Chef::Exceptions::AuditNameMissing)
+ expect{ auditor.control_group do end }.to raise_error(Chef::Exceptions::AuditNameMissing)
end
context "audits already populated" do
let(:audits) { {"unique" => {} } }
it "raises an error if the audit name is a duplicate" do
- expect { auditor.controls "unique" do end }.to raise_error(Chef::Exceptions::AuditControlGroupDuplicate)
+ expect { auditor.control_group "unique" do end }.to raise_error(Chef::Exceptions::AuditControlGroupDuplicate)
end
end
@@ -36,7 +36,7 @@ describe Chef::DSL::Audit do
let(:auditor) { BadAuditDSLTester.new }
it "fails because it relies on the recipe DSL existing" do
- expect { auditor.controls "unique" do end }.to raise_error(NoMethodError, /undefined method `cookbook_name'/)
+ expect { auditor.control_group "unique" do end }.to raise_error(NoMethodError, /undefined method `cookbook_name'/)
end
end
diff --git a/spec/unit/encrypted_data_bag_item_spec.rb b/spec/unit/encrypted_data_bag_item_spec.rb
index 14afea507c..0a4306727b 100644
--- a/spec/unit/encrypted_data_bag_item_spec.rb
+++ b/spec/unit/encrypted_data_bag_item_spec.rb
@@ -124,14 +124,6 @@ describe Chef::EncryptedDataBagItem::Encryptor do
context "on unsupported platforms" do
let(:aead_algorithm) { Chef::EncryptedDataBagItem::AEAD_ALGORITHM }
- it "throws an error warning about the Ruby version if it has no GCM support" do
- # Force OpenSSL with AEAD support
- allow(OpenSSL::Cipher).to receive(:ciphers).and_return([ aead_algorithm ])
- # Ruby without AEAD support
- expect(OpenSSL::Cipher).to receive(:method_defined?).with(:auth_data=).and_return(false)
- expect { encryptor }.to raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires Ruby/)
- end
-
it "throws an error warning about the OpenSSL version if it has no GCM support" do
# Force Ruby with AEAD support
allow(OpenSSL::Cipher).to receive(:method_defined?).with(:auth_data=).and_return(true)
@@ -140,14 +132,6 @@ describe Chef::EncryptedDataBagItem::Encryptor do
expect { encryptor }.to raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires an OpenSSL/)
end
- context "on platforms with old Ruby", :ruby_lt_20 do
-
- it "throws an error warning about the Ruby version" do
- expect { encryptor }.to raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires Ruby/)
- end
-
- end # context on platforms with old Ruby
-
context "on platforms with old OpenSSL", :openssl_lt_101 do
it "throws an error warning about the OpenSSL version" do
@@ -214,14 +198,6 @@ describe Chef::EncryptedDataBagItem::Decryptor do
}
end
- context "on platforms with old Ruby", :ruby_lt_20 do
-
- it "throws an error warning about the Ruby version" do
- expect { decryptor }.to raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires Ruby/)
- end
-
- end # context on platforms with old Ruby
-
context "on platforms with old OpenSSL", :openssl_lt_101 do
it "throws an error warning about the OpenSSL version" do
diff --git a/spec/unit/knife/client_create_spec.rb b/spec/unit/knife/client_create_spec.rb
index 8e7cc4a5e3..10d386b5ff 100644
--- a/spec/unit/knife/client_create_spec.rb
+++ b/spec/unit/knife/client_create_spec.rb
@@ -21,82 +21,96 @@ require 'spec_helper'
Chef::Knife::ClientCreate.load_deps
describe Chef::Knife::ClientCreate do
+ let(:stderr) { StringIO.new }
+
+ let(:default_client_hash) do
+ {
+ "name" => "adam",
+ "validator" => false,
+ "admin" => false
+ }
+ end
+
+ let(:client) do
+ c = double("Chef::ApiClient")
+ allow(c).to receive(:save).and_return({"private_key" => ""})
+ allow(c).to receive(:to_s).and_return("client[adam]")
+ c
+ end
+
+ let(:knife) do
+ k = Chef::Knife::ClientCreate.new
+ k.name_args = [ "adam" ]
+ k.ui.config[:disable_editing] = true
+ allow(k.ui).to receive(:stderr).and_return(stderr)
+ allow(k.ui).to receive(:stdout).and_return(stderr)
+ k
+ end
+
before(:each) do
Chef::Config[:node_name] = "webmonkey.example.com"
- @knife = Chef::Knife::ClientCreate.new
- @knife.config = {
- :file => nil,
- :admin => false,
- :validator => false
- }
- @knife.name_args = [ "adam" ]
- @client = Chef::ApiClient.new
- allow(@client).to receive(:save).and_return({ 'private_key' => '' })
- allow(@knife).to receive(:edit_data).and_return(@client)
- allow(@knife).to receive(:puts)
- allow(Chef::ApiClient).to receive(:new).and_return(@client)
- @stderr = StringIO.new
- allow(@knife.ui).to receive(:stderr).and_return(@stderr)
end
describe "run" do
- it "should create a new Client" do
- expect(Chef::ApiClient).to receive(:new).and_return(@client)
- @knife.run
- expect(@stderr.string).to match /created client.+adam/i
+ it "should create and save the ApiClient" do
+ expect(Chef::ApiClient).to receive(:from_hash).and_return(client)
+ expect(client).to receive(:save)
+ knife.run
+ end
+
+ it "should print a message upon creation" do
+ expect(Chef::ApiClient).to receive(:from_hash).and_return(client)
+ expect(client).to receive(:save)
+ knife.run
+ expect(stderr.string).to match /Created client.*adam/i
end
it "should set the Client name" do
- expect(@client).to receive(:name).with("adam")
- @knife.run
+ expect(Chef::ApiClient).to receive(:from_hash).with(hash_including("name" => "adam")).and_return(client)
+ knife.run
end
it "by default it is not an admin" do
- expect(@client).to receive(:admin).with(false)
- @knife.run
+ expect(Chef::ApiClient).to receive(:from_hash).with(hash_including("admin" => false)).and_return(client)
+ knife.run
end
it "by default it is not a validator" do
- expect(@client).to receive(:validator).with(false)
- @knife.run
+ expect(Chef::ApiClient).to receive(:from_hash).with(hash_including("validator" => false)).and_return(client)
+ knife.run
end
it "should allow you to edit the data" do
- expect(@knife).to receive(:edit_data).with(@client)
- @knife.run
- end
-
- it "should save the Client" do
- expect(@client).to receive(:save)
- @knife.run
+ expect(knife).to receive(:edit_hash).with(default_client_hash).and_return(default_client_hash)
+ allow(Chef::ApiClient).to receive(:from_hash).and_return(client)
+ knife.run
end
describe "with -f or --file" do
it "should write the private key to a file" do
- @knife.config[:file] = "/tmp/monkeypants"
- allow(@client).to receive(:save).and_return({ 'private_key' => "woot" })
+ knife.config[:file] = "/tmp/monkeypants"
+ allow_any_instance_of(Chef::ApiClient).to receive(:save).and_return({ 'private_key' => "woot" })
filehandle = double("Filehandle")
expect(filehandle).to receive(:print).with('woot')
expect(File).to receive(:open).with("/tmp/monkeypants", "w").and_yield(filehandle)
- @knife.run
+ knife.run
end
end
describe "with -a or --admin" do
it "should create an admin client" do
- @knife.config[:admin] = true
- expect(@client).to receive(:admin).with(true)
- @knife.run
+ knife.config[:admin] = true
+ expect(Chef::ApiClient).to receive(:from_hash).with(hash_including("admin" => true)).and_return(client)
+ knife.run
end
end
describe "with --validator" do
it "should create an validator client" do
- @knife.config[:validator] = true
- expect(@client).to receive(:validator).with(true)
- @knife.run
+ knife.config[:validator] = true
+ expect(Chef::ApiClient).to receive(:from_hash).with(hash_including("validator" => true)).and_return(client)
+ knife.run
end
end
-
end
end
diff --git a/spec/unit/knife/cookbook_site_share_spec.rb b/spec/unit/knife/cookbook_site_share_spec.rb
index 0f97261ad4..515a1603ad 100644
--- a/spec/unit/knife/cookbook_site_share_spec.rb
+++ b/spec/unit/knife/cookbook_site_share_spec.rb
@@ -108,11 +108,20 @@ describe Chef::Knife::CookbookSiteShare do
expect { @knife.run }.to raise_error(SystemExit)
end
- it 'should make a tarball of the cookbook' do
- expect(@knife).to receive(:shell_out!) do |args|
- expect(args.to_s).to match(/tar -czf/)
+ if File.exists?('/usr/bin/gnutar') || File.exists?('/bin/gnutar')
+ it 'should use gnutar to make a tarball of the cookbook' do
+ expect(@knife).to receive(:shell_out!) do |args|
+ expect(args.to_s).to match(/gnutar -czf/)
+ end
+ @knife.run
+ end
+ else
+ it 'should make a tarball of the cookbook' do
+ expect(@knife).to receive(:shell_out!) do |args|
+ expect(args.to_s).to match(/tar -czf/)
+ end
+ @knife.run
end
- @knife.run
end
it 'should exit and log to error when the tarball creation fails' do
diff --git a/spec/unit/knife/cookbook_upload_spec.rb b/spec/unit/knife/cookbook_upload_spec.rb
index 5dbd456ad8..fb94886cad 100644
--- a/spec/unit/knife/cookbook_upload_spec.rb
+++ b/spec/unit/knife/cookbook_upload_spec.rb
@@ -246,28 +246,62 @@ E
describe 'with -a or --all' do
before(:each) do
knife.config[:all] = true
- @test_cookbook1 = Chef::CookbookVersion.new('test_cookbook1', '/tmp/blah')
- @test_cookbook2 = Chef::CookbookVersion.new('test_cookbook2', '/tmp/blah')
- allow(cookbook_loader).to receive(:each).and_yield("test_cookbook1", @test_cookbook1).and_yield("test_cookbook2", @test_cookbook2)
- allow(cookbook_loader).to receive(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2"])
end
- it 'should upload all cookbooks' do
- expect(knife).to receive(:upload).once
- knife.run
- end
+ context 'when cookbooks exist in the cookbook path' do
+ before(:each) do
+ @test_cookbook1 = Chef::CookbookVersion.new('test_cookbook1', '/tmp/blah')
+ @test_cookbook2 = Chef::CookbookVersion.new('test_cookbook2', '/tmp/blah')
+ allow(cookbook_loader).to receive(:each).and_yield("test_cookbook1", @test_cookbook1).and_yield("test_cookbook2", @test_cookbook2)
+ allow(cookbook_loader).to receive(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2"])
+ end
- it 'should report on success' do
- expect(knife).to receive(:upload).once
- expect(knife.ui).to receive(:info).with(/Uploaded all cookbooks/)
- knife.run
+ it 'should upload all cookbooks' do
+ expect(knife).to receive(:upload).once
+ knife.run
+ end
+
+ it 'should report on success' do
+ expect(knife).to receive(:upload).once
+ expect(knife.ui).to receive(:info).with(/Uploaded all cookbooks/)
+ knife.run
+ end
+
+ it 'should update the version constraints for an environment' do
+ allow(knife).to receive(:assert_environment_valid!).and_return(true)
+ knife.config[:environment] = "production"
+ expect(knife).to receive(:update_version_constraints).once
+ knife.run
+ end
end
- it 'should update the version constraints for an environment' do
- allow(knife).to receive(:assert_environment_valid!).and_return(true)
- knife.config[:environment] = "production"
- expect(knife).to receive(:update_version_constraints).once
- knife.run
+ context 'when no cookbooks exist in the cookbook path' do
+ before(:each) do
+ allow(cookbook_loader).to receive(:each)
+ end
+
+ it 'should not upload any cookbooks' do
+ expect(knife).to_not receive(:upload)
+ knife.run
+ end
+
+ context 'when cookbook path is an array' do
+ it 'should warn users that no cookbooks exist' do
+ knife.config[:cookbook_path] = ['/chef-repo/cookbooks', '/home/user/cookbooks']
+ expect(knife.ui).to receive(:warn).with(
+ /Could not find any cookbooks in your cookbook path: #{knife.config[:cookbook_path].join(', ')}\. Use --cookbook-path to specify the desired path\./)
+ knife.run
+ end
+ end
+
+ context 'when cookbook path is a string' do
+ it 'should warn users that no cookbooks exist' do
+ knife.config[:cookbook_path] = '/chef-repo/cookbooks'
+ expect(knife.ui).to receive(:warn).with(
+ /Could not find any cookbooks in your cookbook path: #{knife.config[:cookbook_path]}\. Use --cookbook-path to specify the desired path\./)
+ knife.run
+ end
+ end
end
end
diff --git a/spec/unit/knife/raw_spec.rb b/spec/unit/knife/raw_spec.rb
new file mode 100644
index 0000000000..ab929abd39
--- /dev/null
+++ b/spec/unit/knife/raw_spec.rb
@@ -0,0 +1,43 @@
+#
+# Author:: Steven Danna (<steve@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::Knife::Raw do
+ let(:rest) do
+ r = double('Chef::Knife::Raw::RawInputServerAPI')
+ allow(Chef::Knife::Raw::RawInputServerAPI).to receive(:new).and_return(r)
+ r
+ end
+
+ let(:knife) do
+ k = Chef::Knife::Raw.new
+ k.config[:method] = "GET"
+ k.name_args = [ "/nodes" ]
+ k
+ end
+
+ describe "run" do
+ it "should set the x-ops-request-source header when --proxy-auth is set" do
+ knife.config[:proxy_auth] = true
+ expect(rest).to receive(:request).with(:GET, "/nodes",
+ { 'Content-Type' => 'application/json',
+ 'x-ops-request-source' => 'web'}, false)
+ knife.run
+ end
+ end
+end
diff --git a/spec/unit/knife/role_env_run_list_add_spec.rb b/spec/unit/knife/role_env_run_list_add_spec.rb
new file mode 100644
index 0000000000..f286d5fd0d
--- /dev/null
+++ b/spec/unit/knife/role_env_run_list_add_spec.rb
@@ -0,0 +1,217 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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::Knife::RoleEnvRunListAdd do
+ before(:each) do
+# Chef::Config[:role_name] = "websimian"
+# Chef::Config[:env_name] = "QA"
+ @knife = Chef::Knife::RoleEnvRunListAdd.new
+ @knife.config = {
+ :after => nil
+ }
+ @knife.name_args = [ "will", "QA", "role[monkey]" ]
+ allow(@knife).to receive(:output).and_return(true)
+ @role = Chef::Role.new()
+ allow(@role).to receive(:save).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+ end
+
+ describe "run" do
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should have an empty default run list" do
+ @knife.run
+ expect(@role.run_list[0]).to be_nil
+ end
+
+ it "should have a QA environment" do
+ @knife.run
+ expect(@role.active_run_list_for('QA')).to eq('QA')
+ end
+
+ it "should load the role named will" do
+ expect(Chef::Role).to receive(:load).with("will")
+ @knife.run
+ end
+
+ it "should be able to add an environment specific run list" do
+ @knife.run
+ expect(@role.run_list_for('QA')[0]).to eq('role[monkey]')
+ end
+
+ it "should save the role" do
+ expect(@role).to receive(:save)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.run
+ end
+
+ describe "with -a or --after specified" do
+ it "should not create a change if the specified 'after' never comes" do
+ @role.run_list_for("_default") << "role[acorns]"
+ @role.run_list_for("_default") << "role[barn]"
+ @knife.config[:after] = "role[acorns]"
+ @knife.name_args = [ "will", "QA", "role[pad]" ]
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to be_nil
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[barn]")
+ expect(@role.run_list[2]).to be_nil
+ end
+
+ it "should add to the run list after the specified entries in the QA run list" do
+ #Setup
+ @role.run_list_for("_default") << "role[acorns]"
+ @role.run_list_for("_default") << "role[barn]"
+ @knife.run
+ @role.run_list_for("QA") << "role[pencil]"
+ @role.run_list_for("QA") << "role[pen]"
+ #Configuration we are testing
+ @knife.config[:after] = "role[pencil]"
+ @knife.name_args = [ "will", "QA", "role[pad]", "role[whackadoo]" ]
+ @knife.run
+ #The actual tests
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[pencil]")
+ expect(@role.run_list_for("QA")[2]).to eq("role[pad]")
+ expect(@role.run_list_for("QA")[3]).to eq("role[whackadoo]")
+ expect(@role.run_list_for("QA")[4]).to eq("role[pen]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[barn]")
+ expect(@role.run_list[2]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe" do
+ it "should add to the QA run list all the entries" do
+ @knife.name_args = [ "will", "QA", "role[monkey],role[duck]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[duck]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe with space between items" do
+ it "should add to the run list all the entries" do
+ @knife.name_args = [ "will", "QA", "role[monkey], role[duck]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[duck]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe as different arguments" do
+ it "should add to the run list all the entries" do
+ @knife.name_args = [ "will", "QA", "role[monkey]", "role[duck]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[duck]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe as different arguments and list separated by comas" do
+ it "should add to the run list all the entries" do
+ @knife.name_args = [ "will", "QA", "role[monkey]", "role[duck],recipe[bird::fly]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[duck]")
+ expect(@role.run_list_for("QA")[2]).to eq("recipe[bird::fly]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ describe "Recipe with version number is allowed" do
+ it "should add to the run list all the entries including the versioned recipe" do
+ @knife.name_args = [ "will", "QA", "role[monkey]", "role[duck],recipe[bird::fly@1.1.3]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[duck]")
+ expect(@role.run_list_for("QA")[2]).to eq("recipe[bird::fly@1.1.3]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ describe "with one role or recipe but with an extraneous comma" do
+ it "should add to the run list one item" do
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.name_args = [ "will", "QA", "role[monkey]," ]
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to be_nil
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ describe "with more than one command" do
+ it "should be able to the environment run list by running multiple knife commands" do
+ @knife.name_args = [ "will", "QA", "role[blue]," ]
+ @knife.run
+ @knife.name_args = [ "will", "QA", "role[black]," ]
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[blue]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[black]")
+ expect(@role.run_list[0]).to be_nil
+ end
+ end
+
+ describe "with more than one environment" do
+ it "should add to the run list a second environment in the specific run list" do
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.name_args = [ "will", "QA", "role[blue]," ]
+ @knife.run
+ @role.run_list_for("QA") << "role[walnuts]"
+
+ @knife.name_args = [ "will", "PRD", "role[ball]," ]
+ @knife.run
+ @role.run_list_for("PRD") << "role[pen]"
+
+ expect(@role.run_list_for("QA")[0]).to eq("role[blue]")
+ expect(@role.run_list_for("PRD")[0]).to eq("role[ball]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[walnuts]")
+ expect(@role.run_list_for("PRD")[1]).to eq("role[pen]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ end
+end
diff --git a/spec/unit/knife/role_env_run_list_clear_spec.rb b/spec/unit/knife/role_env_run_list_clear_spec.rb
new file mode 100644
index 0000000000..525376c358
--- /dev/null
+++ b/spec/unit/knife/role_env_run_list_clear_spec.rb
@@ -0,0 +1,100 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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::Knife::RoleEnvRunListClear do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ Chef::Config[:env_name] = "QA"
+ @setup = Chef::Knife::RoleEnvRunListAdd.new
+ @setup.name_args = [ "will", "QA", "role[monkey]", "role[person]" ]
+
+ @knife = Chef::Knife::RoleEnvRunListClear.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "QA" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should remove the item from the run list" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list_for('QA')[0]).to be_nil
+ expect(@role.run_list[0]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "should clear an environmental run list of roles and recipes" do
+ it "should remove the items from the run list" do
+ @setup.name_args = [ "will", "QA", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @setup.name_args = [ "will", "PRD", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ 'will', 'QA' ]
+ @knife.run
+ expect(@role.run_list_for('QA')[0]).to be_nil
+ expect(@role.run_list_for('PRD')[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list_for('PRD')[1]).to eq('role[monkey]')
+ expect(@role.run_list_for('PRD')[2]).to eq('recipe[duck::type]')
+ expect(@role.run_list_for('PRD')[3]).to eq('role[person]')
+ expect(@role.run_list_for('PRD')[4]).to eq('role[bird]')
+ expect(@role.run_list_for('PRD')[5]).to eq('role[town]')
+ end
+ end
+ end
+end
+
+
+
diff --git a/spec/unit/knife/role_env_run_list_remove_spec.rb b/spec/unit/knife/role_env_run_list_remove_spec.rb
new file mode 100644
index 0000000000..a15d0af691
--- /dev/null
+++ b/spec/unit/knife/role_env_run_list_remove_spec.rb
@@ -0,0 +1,108 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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::Knife::RoleEnvRunListRemove do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ Chef::Config[:env_name] = "QA"
+ @setup = Chef::Knife::RoleEnvRunListAdd.new
+ @setup.name_args = [ "will", "QA", "role[monkey]", "role[person]" ]
+
+ @knife = Chef::Knife::RoleEnvRunListRemove.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "QA", "role[monkey]" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should remove the item from the run list" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list_for('QA')[0]).not_to eq('role[monkey]')
+ expect(@role.run_list_for('QA')[0]).to eq('role[person]')
+ expect(@role.run_list[0]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "run with a list of roles and recipes" do
+ it "should remove the items from the run list" do
+ @setup.name_args = [ "will", "QA", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @setup.name_args = [ "will", "PRD", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ 'will', 'QA', 'role[monkey]' ]
+ @knife.run
+ @knife.name_args = [ 'will', 'QA', 'recipe[duck::type]' ]
+ @knife.run
+ expect(@role.run_list_for('QA')).not_to include('role[monkey]')
+ expect(@role.run_list_for('QA')).not_to include('recipe[duck::type]')
+ expect(@role.run_list_for('QA')[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list_for('QA')[1]).to eq('role[person]')
+ expect(@role.run_list_for('QA')[2]).to eq('role[bird]')
+ expect(@role.run_list_for('QA')[3]).to eq('role[town]')
+ expect(@role.run_list_for('PRD')[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list_for('PRD')[1]).to eq('role[monkey]')
+ expect(@role.run_list_for('PRD')[2]).to eq('recipe[duck::type]')
+ expect(@role.run_list_for('PRD')[3]).to eq('role[person]')
+ expect(@role.run_list_for('PRD')[4]).to eq('role[bird]')
+ expect(@role.run_list_for('PRD')[5]).to eq('role[town]')
+ end
+ end
+ end
+end
+
+
+
diff --git a/spec/unit/knife/role_env_run_list_replace_spec.rb b/spec/unit/knife/role_env_run_list_replace_spec.rb
new file mode 100644
index 0000000000..ea48601b8d
--- /dev/null
+++ b/spec/unit/knife/role_env_run_list_replace_spec.rb
@@ -0,0 +1,108 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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::Knife::RoleEnvRunListReplace do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ Chef::Config[:env_name] = "QA"
+ @setup = Chef::Knife::RoleEnvRunListAdd.new
+ @setup.name_args = [ "will", "QA", "role[monkey]", "role[dude]", "role[fixer]" ]
+
+ @knife = Chef::Knife::RoleEnvRunListReplace.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "QA", "role[dude]", "role[person]" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should remove the item from the run list" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list_for('QA')[1]).not_to eq('role[dude]')
+ expect(@role.run_list_for('QA')[1]).to eq('role[person]')
+ expect(@role.run_list[0]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "run with a list of roles and recipes" do
+ it "should replace the items from the run list" do
+ @setup.name_args = [ "will", "QA", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @setup.name_args = [ "will", "PRD", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ 'will', 'QA', 'role[monkey]', 'role[gibbon]' ]
+ @knife.run
+ @knife.name_args = [ 'will', 'QA', 'recipe[duck::type]', 'recipe[duck::mallard]' ]
+ @knife.run
+ expect(@role.run_list_for('QA')).not_to include('role[monkey]')
+ expect(@role.run_list_for('QA')).not_to include('recipe[duck::type]')
+ expect(@role.run_list_for('QA')[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list_for('QA')[1]).to eq('role[gibbon]')
+ expect(@role.run_list_for('QA')[2]).to eq('recipe[duck::mallard]')
+ expect(@role.run_list_for('QA')[3]).to eq('role[person]')
+ expect(@role.run_list_for('QA')[4]).to eq('role[bird]')
+ expect(@role.run_list_for('QA')[5]).to eq('role[town]')
+ expect(@role.run_list_for('PRD')[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list_for('PRD')[1]).to eq('role[monkey]')
+ expect(@role.run_list_for('PRD')[2]).to eq('recipe[duck::type]')
+ expect(@role.run_list_for('PRD')[3]).to eq('role[person]')
+ expect(@role.run_list_for('PRD')[4]).to eq('role[bird]')
+ expect(@role.run_list_for('PRD')[5]).to eq('role[town]')
+ expect(@role.run_list[0]).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/unit/knife/role_env_run_list_set_spec.rb b/spec/unit/knife/role_env_run_list_set_spec.rb
new file mode 100644
index 0000000000..f3abb86fcf
--- /dev/null
+++ b/spec/unit/knife/role_env_run_list_set_spec.rb
@@ -0,0 +1,102 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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::Knife::RoleEnvRunListSet do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ Chef::Config[:env_name] = "QA"
+ @setup = Chef::Knife::RoleEnvRunListAdd.new
+ @setup.name_args = [ "will", "QA", "role[monkey]", "role[person]", "role[bucket]" ]
+
+ @knife = Chef::Knife::RoleEnvRunListSet.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "QA", "role[owen]", "role[mauntel]" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should replace all the items in the runlist with what is specified" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list_for('QA')[0]).to eq("role[owen]")
+ expect(@role.run_list_for('QA')[1]).to eq("role[mauntel]")
+ expect(@role.run_list_for('QA')[2]).to be_nil
+ expect(@role.run_list[0]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "should clear an environmental run list of roles and recipes" do
+ it "should remove the items from the run list" do
+ @setup.name_args = [ "will", "QA", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @setup.name_args = [ "will", "PRD", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ "will", "QA", "role[coke]", "role[pepsi]" ]
+ @knife.run
+ expect(@role.run_list_for('QA')[0]).to eq("role[coke]")
+ expect(@role.run_list_for('QA')[1]).to eq("role[pepsi]")
+ expect(@role.run_list_for('QA')[2]).to be_nil
+ expect(@role.run_list_for('PRD')[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list_for('PRD')[1]).to eq('role[monkey]')
+ expect(@role.run_list_for('PRD')[2]).to eq('recipe[duck::type]')
+ expect(@role.run_list_for('PRD')[3]).to eq('role[person]')
+ expect(@role.run_list_for('PRD')[4]).to eq('role[bird]')
+ expect(@role.run_list_for('PRD')[5]).to eq('role[town]')
+ expect(@role.run_list[0]).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/unit/knife/role_run_list_add_spec.rb b/spec/unit/knife/role_run_list_add_spec.rb
new file mode 100644
index 0000000000..d61c114912
--- /dev/null
+++ b/spec/unit/knife/role_run_list_add_spec.rb
@@ -0,0 +1,179 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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::Knife::RoleRunListAdd do
+ before(:each) do
+# Chef::Config[:role_name] = "websimian"
+# Chef::Config[:env_name] = "QA"
+ @knife = Chef::Knife::RoleRunListAdd.new
+ @knife.config = {
+ :after => nil
+ }
+ @knife.name_args = [ "will", "role[monkey]" ]
+ allow(@knife).to receive(:output).and_return(true)
+ @role = Chef::Role.new()
+ allow(@role).to receive(:save).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+ end
+
+ describe "run" do
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should have a run list with the monkey role" do
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[monkey]")
+ end
+
+ it "should load the role named will" do
+ expect(Chef::Role).to receive(:load).with("will")
+ @knife.run
+ end
+
+ it "should save the role" do
+ expect(@role).to receive(:save)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.run
+ end
+
+ describe "with -a or --after specified" do
+ it "should not create a change if the specified 'after' never comes" do
+ @role.run_list_for("_default") << "role[acorns]"
+ @role.run_list_for("_default") << "role[barn]"
+ @knife.config[:after] = "role[tree]"
+ @knife.name_args = [ "will", "role[pad]" ]
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[barn]")
+ expect(@role.run_list[2]).to be_nil
+ end
+
+ it "should add to the run list after the specified entries in the default run list" do
+ #Setup
+ @role.run_list_for("_default") << "role[acorns]"
+ @role.run_list_for("_default") << "role[barn]"
+ #Configuration we are testing
+ @knife.config[:after] = "role[acorns]"
+ @knife.name_args = [ "will", "role[pad]", "role[whackadoo]" ]
+ @knife.run
+ #The actual tests
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[pad]")
+ expect(@role.run_list[2]).to eq("role[whackadoo]")
+ expect(@role.run_list[3]).to eq("role[barn]")
+ expect(@role.run_list[4]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe" do
+ it "should add to the QA run list all the entries" do
+ @knife.name_args = [ "will", "role[monkey],role[duck]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[monkey]")
+ expect(@role.run_list[2]).to eq("role[duck]")
+ expect(@role.run_list[3]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe with space between items" do
+ it "should add to the run list all the entries" do
+ @knife.name_args = [ "will", "role[monkey], role[duck]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[monkey]")
+ expect(@role.run_list[2]).to eq("role[duck]")
+ expect(@role.run_list[3]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe as different arguments" do
+ it "should add to the run list all the entries" do
+ @knife.name_args = [ "will", "role[monkey]", "role[duck]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[monkey]")
+ expect(@role.run_list[2]).to eq("role[duck]")
+ expect(@role.run_list[3]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe as different arguments and list separated by comas" do
+ it "should add to the run list all the entries" do
+ @knife.name_args = [ "will", "role[monkey]", "role[duck],recipe[bird::fly]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[monkey]")
+ expect(@role.run_list[2]).to eq("role[duck]")
+ expect(@role.run_list[3]).to eq("recipe[bird::fly]")
+ expect(@role.run_list[4]).to be_nil
+ end
+ end
+
+ describe "Recipe with version number is allowed" do
+ it "should add to the run list all the entries including the versioned recipe" do
+ @knife.name_args = [ "will", "role[monkey]", "role[duck],recipe[bird::fly@1.1.3]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[monkey]")
+ expect(@role.run_list[2]).to eq("role[duck]")
+ expect(@role.run_list[3]).to eq("recipe[bird::fly@1.1.3]")
+ expect(@role.run_list[4]).to be_nil
+ end
+ end
+
+ describe "with one role or recipe but with an extraneous comma" do
+ it "should add to the run list one item" do
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.name_args = [ "will", "role[monkey]," ]
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[monkey]")
+ expect(@role.run_list[2]).to be_nil
+ end
+ end
+
+ describe "with more than one command" do
+ it "should be able to the environment run list by running multiple knife commands" do
+ @knife.name_args = [ "will", "role[blue]," ]
+ @knife.run
+ @knife.name_args = [ "will", "role[black]," ]
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[blue]")
+ expect(@role.run_list[1]).to eq("role[black]")
+ expect(@role.run_list[2]).to be_nil
+ end
+ end
+
+ end
+end
diff --git a/spec/unit/knife/role_run_list_clear_spec.rb b/spec/unit/knife/role_run_list_clear_spec.rb
new file mode 100644
index 0000000000..e5a6e18673
--- /dev/null
+++ b/spec/unit/knife/role_run_list_clear_spec.rb
@@ -0,0 +1,90 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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::Knife::RoleRunListClear do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ @setup = Chef::Knife::RoleRunListAdd.new
+ @setup.name_args = [ "will", "role[monkey]", "role[person]" ]
+
+ @knife = Chef::Knife::RoleRunListClear.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should remove the item from the run list" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list[0]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "should clear an environmental run list of roles and recipes" do
+ it "should remove the items from the run list" do
+ @setup.name_args = [ "will", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ 'will' ]
+ @knife.run
+ expect(@role.run_list[0]).to be_nil
+ end
+ end
+ end
+end
+
+
+
diff --git a/spec/unit/knife/role_run_list_remove_spec.rb b/spec/unit/knife/role_run_list_remove_spec.rb
new file mode 100644
index 0000000000..0f4adf253b
--- /dev/null
+++ b/spec/unit/knife/role_run_list_remove_spec.rb
@@ -0,0 +1,98 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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::Knife::RoleRunListRemove do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ @setup = Chef::Knife::RoleRunListAdd.new
+ @setup.name_args = [ "will", "role[monkey]", "role[person]" ]
+
+ @knife = Chef::Knife::RoleRunListRemove.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "role[monkey]" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should remove the item from the run list" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list[0]).to eq('role[person]')
+ expect(@role.run_list[1]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "run with a list of roles and recipes" do
+ it "should remove the items from the run list" do
+ @setup.name_args = [ "will", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ 'will', 'role[monkey]' ]
+ @knife.run
+ @knife.name_args = [ 'will', 'recipe[duck::type]' ]
+ @knife.run
+ expect(@role.run_list).not_to include('role[monkey]')
+ expect(@role.run_list).not_to include('recipe[duck::type]')
+ expect(@role.run_list[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list[1]).to eq('role[person]')
+ expect(@role.run_list[2]).to eq('role[bird]')
+ expect(@role.run_list[3]).to eq('role[town]')
+ end
+ end
+ end
+end
+
+
+
diff --git a/spec/unit/knife/role_run_list_replace_spec.rb b/spec/unit/knife/role_run_list_replace_spec.rb
new file mode 100644
index 0000000000..2ff38f573c
--- /dev/null
+++ b/spec/unit/knife/role_run_list_replace_spec.rb
@@ -0,0 +1,101 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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::Knife::RoleRunListReplace do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ @setup = Chef::Knife::RoleRunListAdd.new
+ @setup.name_args = [ "will", "role[monkey]", "role[dude]", "role[fixer]" ]
+
+ @knife = Chef::Knife::RoleRunListReplace.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "role[dude]", "role[person]" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should remove the item from the run list" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list[0]).to eq('role[monkey]')
+ expect(@role.run_list[1]).not_to eq('role[dude]')
+ expect(@role.run_list[1]).to eq('role[person]')
+ expect(@role.run_list[2]).to eq('role[fixer]')
+ expect(@role.run_list[3]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "run with a list of roles and recipes" do
+ it "should replace the items from the run list" do
+ @setup.name_args = [ "will", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ 'will', 'role[monkey]', 'role[gibbon]' ]
+ @knife.run
+ @knife.name_args = [ 'will', 'recipe[duck::type]', 'recipe[duck::mallard]' ]
+ @knife.run
+ expect(@role.run_list).not_to include('role[monkey]')
+ expect(@role.run_list).not_to include('recipe[duck::type]')
+ expect(@role.run_list[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list[1]).to eq('role[gibbon]')
+ expect(@role.run_list[2]).to eq('recipe[duck::mallard]')
+ expect(@role.run_list[3]).to eq('role[person]')
+ expect(@role.run_list[4]).to eq('role[bird]')
+ expect(@role.run_list[5]).to eq('role[town]')
+ expect(@role.run_list[6]).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/unit/knife/role_run_list_set_spec.rb b/spec/unit/knife/role_run_list_set_spec.rb
new file mode 100644
index 0000000000..1350741f10
--- /dev/null
+++ b/spec/unit/knife/role_run_list_set_spec.rb
@@ -0,0 +1,92 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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::Knife::RoleRunListSet do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ @setup = Chef::Knife::RoleRunListAdd.new
+ @setup.name_args = [ "will", "role[monkey]", "role[person]", "role[bucket]" ]
+
+ @knife = Chef::Knife::RoleRunListSet.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "role[owen]", "role[mauntel]" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should replace all the items in the runlist with what is specified" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[owen]")
+ expect(@role.run_list[1]).to eq("role[mauntel]")
+ expect(@role.run_list[2]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "should clear an environmental run list of roles and recipes" do
+ it "should remove the items from the run list" do
+ @setup.name_args = [ "will", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ "will", "role[coke]", "role[pepsi]" ]
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[coke]")
+ expect(@role.run_list[1]).to eq("role[pepsi]")
+ expect(@role.run_list[2]).to be_nil
+ expect(@role.run_list[3]).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/unit/lwrp_spec.rb b/spec/unit/lwrp_spec.rb
index 35963dec64..ec39174da6 100644
--- a/spec/unit/lwrp_spec.rb
+++ b/spec/unit/lwrp_spec.rb
@@ -36,6 +36,30 @@ describe "LWRP" do
allow($stderr).to receive(:write)
end
+ it "should not skip loading a resource when there's a top level symbol of the same name" do
+ Object.const_set('LwrpFoo', Class.new)
+ file = File.expand_path( "lwrp/resources/foo.rb", CHEF_SPEC_DATA)
+ expect(Chef::Log).not_to receive(:info).with(/Skipping/)
+ expect(Chef::Log).not_to receive(:debug).with(/anymore/)
+ Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
+ Object.send(:remove_const, 'LwrpFoo')
+ Chef::Resource.send(:remove_const, 'LwrpFoo')
+ end
+
+ it "should not skip loading a provider when there's a top level symbol of the same name" do
+ Object.const_set('LwrpBuckPasser', Class.new)
+ file = File.expand_path( "lwrp/providers/buck_passer.rb", CHEF_SPEC_DATA)
+ expect(Chef::Log).not_to receive(:info).with(/Skipping/)
+ expect(Chef::Log).not_to receive(:debug).with(/anymore/)
+ Chef::Provider::LWRPBase.build_from_file("lwrp", file, nil)
+ Object.send(:remove_const, 'LwrpBuckPasser')
+ Chef::Provider.send(:remove_const, 'LwrpBuckPasser')
+ end
+
+ # @todo: we need a before block to manually remove_const all of the LWRPs that we
+ # load in these tests. we're threading state through these tests in LWRPs that
+ # have already been loaded in prior tests, which probably renders some of them bogus
+
it "should log if attempting to load resource of same name" do
Dir[File.expand_path( "lwrp/resources/*", CHEF_SPEC_DATA)].each do |file|
Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
@@ -317,8 +341,8 @@ describe "LWRP" do
Chef::Runner.new(@run_context).converge
expect(@run_context.resource_collection[0]).to eql(injector)
- expect(@run_context.resource_collection[1].name).to eql(:prepared_thumbs)
- expect(@run_context.resource_collection[2].name).to eql(:twiddled_thumbs)
+ expect(@run_context.resource_collection[1].name).to eql('prepared_thumbs')
+ expect(@run_context.resource_collection[2].name).to eql('twiddled_thumbs')
expect(@run_context.resource_collection[3]).to eql(dummy)
end
@@ -341,12 +365,12 @@ describe "LWRP" do
Chef::Runner.new(@run_context).converge
expect(@run_context.resource_collection[0]).to eql(injector)
- expect(@run_context.resource_collection[1].name).to eql(:prepared_thumbs)
- expect(@run_context.resource_collection[2].name).to eql(:twiddled_thumbs)
+ expect(@run_context.resource_collection[1].name).to eql('prepared_thumbs')
+ expect(@run_context.resource_collection[2].name).to eql('twiddled_thumbs')
expect(@run_context.resource_collection[3]).to eql(dummy)
expect(@run_context.resource_collection[4]).to eql(injector2)
- expect(@run_context.resource_collection[5].name).to eql(:prepared_eyes)
- expect(@run_context.resource_collection[6].name).to eql(:dried_paint_watched)
+ expect(@run_context.resource_collection[5].name).to eql('prepared_eyes')
+ expect(@run_context.resource_collection[6].name).to eql('dried_paint_watched')
end
it "should properly handle a new_resource reference" do
diff --git a/spec/unit/org_spec.rb b/spec/unit/org_spec.rb
new file mode 100644
index 0000000000..cd6cc94d91
--- /dev/null
+++ b/spec/unit/org_spec.rb
@@ -0,0 +1,196 @@
+#
+# Author:: Steven Danna (steve@opscode.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'
+
+require 'chef/org'
+require 'tempfile'
+
+describe Chef::Org do
+ let(:org) { Chef::Org.new("an_org") }
+
+ describe "initialize" do
+ it "is a Chef::Org" do
+ expect(org).to be_a_kind_of(Chef::Org)
+ end
+ end
+
+ describe "name" do
+ it "lets you set the name to a string" do
+ org.name "sg1"
+ expect(org.name).to eq("sg1")
+ end
+
+ # It is not feasible to check all invalid characters. Here are a few
+ # that we probably care about.
+ it "raises on invalid characters" do
+ # capital letters
+ expect { org.name "Bar" }.to raise_error(ArgumentError)
+ # slashes
+ expect { org.name "foo/bar" }.to raise_error(ArgumentError)
+ # ?
+ expect { org.name "foo?" }.to raise_error(ArgumentError)
+ # &
+ expect { org.name "foo&" }.to raise_error(ArgumentError)
+ # spaces
+ expect { org.name "foo " }.to raise_error(ArgumentError)
+ end
+
+ it "raises an ArgumentError if you feed it anything but a string" do
+ expect { org.name Hash.new }.to raise_error(ArgumentError)
+ end
+ end
+
+ describe "full_name" do
+ it "lets you set the full name" do
+ org.full_name "foo"
+ expect(org.full_name).to eq("foo")
+ end
+
+ it "raises an ArgumentError if you feed it anything but a string" do
+ expect { org.name Hash.new }.to raise_error(ArgumentError)
+ end
+ end
+
+ describe "private_key" do
+ it "returns the private key" do
+ org.private_key("super private")
+ expect(org.private_key).to eq("super private")
+ end
+
+ it "raises an ArgumentError if you feed it something lame" do
+ expect { org.private_key Hash.new }.to raise_error(ArgumentError)
+ end
+ end
+
+ describe "when serializing to JSON" do
+ let(:json) do
+ org.name("black")
+ org.full_name("black crowes")
+ org.to_json
+ end
+
+ it "serializes as a JSON object" do
+ expect(json).to match(/^\{.+\}$/)
+ end
+
+ it "includes the name value" do
+ expect(json).to include(%q{"name":"black"})
+ end
+
+ it "includes the full name value" do
+ expect(json).to include(%q{"full_name":"black crowes"})
+ end
+
+ it "includes the private key when present" do
+ org.private_key("monkeypants")
+ expect(org.to_json).to include(%q{"private_key":"monkeypants"})
+ end
+
+ it "does not include the private key if not present" do
+ expect(json).to_not include("private_key")
+ end
+ end
+
+ describe "when deserializing from JSON" do
+ let(:org) do
+ o = { "name" => "turtle",
+ "full_name" => "turtle_club",
+ "private_key" => "pandas" }
+ Chef::Org.from_json(o.to_json)
+ end
+
+ it "deserializes to a Chef::Org object" do
+ expect(org).to be_a_kind_of(Chef::Org)
+ end
+
+ it "preserves the name" do
+ expect(org.name).to eq("turtle")
+ end
+
+ it "preserves the full_name" do
+ expect(org.full_name).to eq("turtle_club")
+ end
+
+ it "includes the private key if present" do
+ expect(org.private_key).to eq("pandas")
+ end
+ end
+
+ describe "API Interactions" do
+ let(:rest) do
+ Chef::Config[:chef_server_root] = "http://www.example.com"
+ r = double('rest')
+ allow(Chef::REST).to receive(:new).and_return(r)
+ r
+ end
+
+ let(:org) do
+ o = Chef::Org.new("foobar")
+ o.full_name "foo bar bat"
+ o
+ end
+
+ describe "list" do
+ let(:response) { {"foobar" => "http://www.example.com/organizations/foobar"} }
+ let(:inflated_response) { {"foobar" => org } }
+
+ it "lists all orgs" do
+ expect(rest).to receive(:get_rest).with("organizations").and_return(response)
+ expect(Chef::Org.list).to eq(response)
+ end
+
+ it "inflate all orgs" do
+ allow(Chef::Org).to receive(:load).with("foobar").and_return(org)
+ expect(rest).to receive(:get_rest).with("organizations").and_return(response)
+ expect(Chef::Org.list(true)).to eq(inflated_response)
+ end
+ end
+
+ describe "create" do
+ it "creates a new org via the API" do
+ expect(rest).to receive(:post_rest).with("organizations", {:name => "foobar", :full_name => "foo bar bat"}).and_return({})
+ org.create
+ end
+ end
+
+ describe "read" do
+ it "loads a named org from the API" do
+ expect(rest).to receive(:get_rest).with("organizations/foobar").and_return({"name" => "foobar", "full_name" => "foo bar bat", "private_key" => "private"})
+ org = Chef::Org.load("foobar")
+ expect(org.name).to eq("foobar")
+ expect(org.full_name).to eq("foo bar bat")
+ expect(org.private_key).to eq("private")
+ end
+ end
+
+ describe "update" do
+ it "updates an existing org on via the API" do
+ expect(rest).to receive(:put_rest).with("organizations/foobar", {:name => "foobar", :full_name => "foo bar bat"}).and_return({})
+ org.update
+ end
+ end
+
+ describe "destroy" do
+ it "deletes the specified org via the API" do
+ expect(rest).to receive(:delete_rest).with("organizations/foobar")
+ org.destroy
+ end
+ end
+ end
+end
diff --git a/spec/unit/policy_builder/policyfile_spec.rb b/spec/unit/policy_builder/policyfile_spec.rb
index 5e2844201d..8b6e928a46 100644
--- a/spec/unit/policy_builder/policyfile_spec.rb
+++ b/spec/unit/policy_builder/policyfile_spec.rb
@@ -144,7 +144,7 @@ describe Chef::PolicyBuilder::Policyfile do
end
- describe "when using compatibility mode" do
+ describe "loading policy data" do
let(:http_api) { double("Chef::REST") }
@@ -171,49 +171,113 @@ describe Chef::PolicyBuilder::Policyfile do
allow(policy_builder).to receive(:http_api).and_return(http_api)
end
- context "when the deployment group cannot be loaded" do
- let(:error404) { Net::HTTPServerException.new("404 message", :body) }
+ describe "when using compatibility mode (policy_document_native_api == false)" do
- before do
- expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
- expect(http_api).to receive(:get).
- with("data/policyfiles/example-policy-stage").
- and_raise(error404)
- end
+ context "when the deployment group cannot be loaded" do
+ let(:error404) { Net::HTTPServerException.new("404 message", :body) }
+
+ before do
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
+ expect(http_api).to receive(:get).
+ with("data/policyfiles/example-policy-stage").
+ and_raise(error404)
+ end
+
+ it "raises an error" do
+ expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
+ end
+
+ it "sends error message to the event system" do
+ expect(events).to receive(:node_load_failed).with(node_name, an_instance_of(err_namespace::ConfigurationError), Chef::Config)
+ expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
+ end
- it "raises an error" do
- expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
end
- it "sends error message to the event system" do
- expect(events).to receive(:node_load_failed).with(node_name, an_instance_of(err_namespace::ConfigurationError), Chef::Config)
- expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
+ context "when the deployment_group is not configured" do
+ before do
+ Chef::Config[:deployment_group] = nil
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
+ end
+
+ it "errors while loading the node" do
+ expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
+ end
+
+
+ it "passes error information to the event system" do
+ # TODO: also make sure something acceptable happens with the error formatters
+ err_class = err_namespace::ConfigurationError
+ expect(events).to receive(:node_load_failed).with(node_name, an_instance_of(err_class), Chef::Config)
+ expect { policy_builder.load_node }.to raise_error(err_class)
+ end
end
+ context "when deployment_group is correctly configured" do
+
+ let(:policy_relative_url) { "data/policyfiles/example-policy-stage" }
+
+ before do
+ expect(http_api).to receive(:get).with(policy_relative_url).and_return(parsed_policyfile_json)
+ end
+
+ it "fetches the policy file from a data bag item" do
+ expect(policy_builder.policy).to eq(parsed_policyfile_json)
+ end
+
+ it "extracts the run_list from the policyfile" do
+ expect(policy_builder.run_list).to eq(policyfile_run_list)
+ end
+
+ end
end
- describe "when the deployment_group is not configured" do
+ context "and policy_document_native_api is configured" do
+
before do
- Chef::Config[:deployment_group] = nil
- expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
+ Chef::Config[:policy_document_native_api] = true
+ Chef::Config[:policy_group] = "policy-stage"
+ Chef::Config[:policy_name] = "example"
end
- it "errors while loading the node" do
- expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
+ context "and policy_name or policy_group are not configured" do
+
+ it "raises a Configuration error for policy_group" do
+ Chef::Config[:policy_group] = nil
+ expect { policy_builder.policy }.to raise_error(err_namespace::ConfigurationError)
+ end
+
+ it "raises a Configuration error for policy_name" do
+ Chef::Config[:policy_name] = nil
+ expect { policy_builder.policy }.to raise_error(err_namespace::ConfigurationError)
+ end
+
end
+ context "and policy_name and policy_group are configured" do
+
+ let(:policy_relative_url) { "policies/policy-stage/example" }
+
+ before do
+ expect(http_api).to receive(:get).with(policy_relative_url).and_return(parsed_policyfile_json)
+ end
+
+ it "fetches the policy file from a data bag item" do
+ expect(policy_builder.policy).to eq(parsed_policyfile_json)
+ end
- it "passes error information to the event system" do
- # TODO: also make sure something acceptable happens with the error formatters
- err_class = err_namespace::ConfigurationError
- expect(events).to receive(:node_load_failed).with(node_name, an_instance_of(err_class), Chef::Config)
- expect { policy_builder.load_node }.to raise_error(err_class)
+ it "extracts the run_list from the policyfile" do
+ expect(policy_builder.run_list).to eq(policyfile_run_list)
+ end
end
+
end
- context "and a deployment_group is configured" do
+
+ describe "building policy from the policyfile" do
+
before do
- expect(http_api).to receive(:get).with("data/policyfiles/example-policy-stage").and_return(parsed_policyfile_json)
+ allow(policy_builder).to receive(:policy).and_return(parsed_policyfile_json)
end
it "fetches the policy file from a data bag item" do
@@ -334,67 +398,91 @@ describe Chef::PolicyBuilder::Policyfile do
let(:cookbook_synchronizer) { double("Chef::CookbookSynchronizer") }
- context "and a cookbook is missing" do
+ shared_examples_for "fetching cookbooks" do
+ context "and a cookbook is missing" do
- let(:error404) { Net::HTTPServerException.new("404 message", :body) }
+ let(:error404) { Net::HTTPServerException.new("404 message", :body) }
- before do
- expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
+ before do
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
- # Remove references to example2 cookbook because we're iterating
- # over a Hash data structure and on ruby 1.8.7 iteration order will
- # not be stable.
- parsed_policyfile_json["cookbook_locks"].delete("example2")
- parsed_policyfile_json["run_list"].delete("recipe[example2::server]")
+ policy_builder.load_node
+ policy_builder.build_node
- policy_builder.load_node
- policy_builder.build_node
+ expect(http_api).to receive(:get).with(cookbook1_url).
+ and_raise(error404)
+ end
- expect(http_api).to receive(:get).with("cookbooks/example1/#{example1_xyz_version}").
- and_raise(error404)
- end
+ it "raises an error indicating which cookbook is missing" do
+ expect { policy_builder.cookbooks_to_sync }.to raise_error(Chef::Exceptions::CookbookNotFound)
+ end
- it "raises an error indicating which cookbook is missing" do
- expect { policy_builder.cookbooks_to_sync }.to raise_error(Chef::Exceptions::CookbookNotFound)
end
- end
+ context "and the cookbooks can be fetched" do
+ before do
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
- context "and the cookbooks can be fetched" do
- before do
- expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
+ policy_builder.load_node
+ policy_builder.build_node
+
+ expect(http_api).to receive(:get).with(cookbook1_url).
+ and_return(example1_cookbook_object)
+ expect(http_api).to receive(:get).with(cookbook2_url).
+ and_return(example2_cookbook_object)
- policy_builder.load_node
- policy_builder.build_node
+ allow(Chef::CookbookSynchronizer).to receive(:new).
+ with(expected_cookbook_hash, events).
+ and_return(cookbook_synchronizer)
+ end
- expect(http_api).to receive(:get).with("cookbooks/example1/#{example1_xyz_version}").
- and_return(example1_cookbook_object)
- expect(http_api).to receive(:get).with("cookbooks/example2/#{example2_xyz_version}").
- and_return(example2_cookbook_object)
+ it "builds a Hash of the form 'cookbook_name' => Chef::CookbookVersion" do
+ expect(policy_builder.cookbooks_to_sync).to eq(expected_cookbook_hash)
+ end
+
+ it "syncs the desired cookbooks via CookbookSynchronizer" do
+ expect(cookbook_synchronizer).to receive(:sync_cookbooks)
+ policy_builder.sync_cookbooks
+ end
+
+ it "builds a run context" do
+ expect(cookbook_synchronizer).to receive(:sync_cookbooks)
+ expect_any_instance_of(Chef::RunContext).to receive(:load).with(policy_builder.run_list_expansion_ish)
+ run_context = policy_builder.setup_run_context
+ expect(run_context.node).to eq(node)
+ expect(run_context.cookbook_collection.keys).to match_array(["example1", "example2"])
+ end
- allow(Chef::CookbookSynchronizer).to receive(:new).
- with(expected_cookbook_hash, events).
- and_return(cookbook_synchronizer)
end
+ end # shared_examples_for "fetching cookbooks"
+
+ context "when using compatibility mode (policy_document_native_api == false)" do
+ include_examples "fetching cookbooks" do
+
+ let(:cookbook1_url) { "cookbooks/example1/#{example1_xyz_version}" }
+ let(:cookbook2_url) { "cookbooks/example2/#{example2_xyz_version}" }
- it "builds a Hash of the form 'cookbook_name' => Chef::CookbookVersion" do
- expect(policy_builder.cookbooks_to_sync).to eq(expected_cookbook_hash)
end
- it "syncs the desired cookbooks via CookbookSynchronizer" do
- expect(cookbook_synchronizer).to receive(:sync_cookbooks)
- policy_builder.sync_cookbooks
+ end
+
+ context "when using native API mode (policy_document_native_api == true)" do
+
+ before do
+ Chef::Config[:policy_document_native_api] = true
+ Chef::Config[:policy_group] = "policy-stage"
+ Chef::Config[:policy_name] = "example"
end
- it "builds a run context" do
- expect(cookbook_synchronizer).to receive(:sync_cookbooks)
- expect_any_instance_of(Chef::RunContext).to receive(:load).with(policy_builder.run_list_expansion_ish)
- run_context = policy_builder.setup_run_context
- expect(run_context.node).to eq(node)
- expect(run_context.cookbook_collection.keys).to match_array(["example1", "example2"])
+ include_examples "fetching cookbooks" do
+
+ let(:cookbook1_url) { "cookbook_artifacts/example1/#{example1_xyz_version}" }
+ let(:cookbook2_url) { "cookbook_artifacts/example2/#{example2_xyz_version}" }
+
end
end
+
end
end
diff --git a/spec/unit/provider/env_spec.rb b/spec/unit/provider/env_spec.rb
index 19233dfba9..230603dcb3 100644
--- a/spec/unit/provider/env_spec.rb
+++ b/spec/unit/provider/env_spec.rb
@@ -252,7 +252,7 @@ describe Chef::Provider::Env do
end
context "when new_resource's value contains the delimiter" do
- it "should return false if all the current values are contained" do
+ it "should return false if all the current values are contained in specified order" do
@new_resource.value("C:/biz;C:/baz")
@new_resource.delim(";")
@current_resource.value("C:/biz;C:/foo/bin;C:/baz")
@@ -265,6 +265,13 @@ describe Chef::Provider::Env do
@current_resource.value("C:/biz;C:/foo/bin;C:/baz")
expect(@provider.requires_modify_or_create?).to be_truthy
end
+
+ it "should return true if values are contained in different order" do
+ @new_resource.value("C:/biz;C:/baz")
+ @new_resource.delim(";")
+ @current_resource.value("C:/baz;C:/foo/bin;C:/biz")
+ expect(@provider.requires_modify_or_create?).to be_truthy
+ end
end
end
@@ -286,12 +293,18 @@ describe Chef::Provider::Env do
expect(passed_value).to eq(new_value)
end
- it "should only add values not already contained when a delimiter is provided" do
+ it "should only add values not already contained" do
@new_resource.value("C:/foo;C:/bar;C:/baz")
- @new_resource.delim(";")
- @current_resource.value("C:/foo/bar;C:/bar;C:/baz")
+ @current_resource.value("C:/bar;C:/baz;C:/foo/bar")
+ @provider.modify_env
+ expect(@new_resource.value).to eq("C:/foo;C:/bar;C:/baz;C:/foo/bar")
+ end
+
+ it "should reorder values to keep order which asked" do
+ @new_resource.value("C:/foo;C:/bar;C:/baz")
+ @current_resource.value("C:/foo/bar;C:/baz;C:/bar")
@provider.modify_env
- expect(@new_resource.value).to eq("C:/foo;C:/foo/bar;C:/bar;C:/baz")
+ expect(@new_resource.value).to eq("C:/foo;C:/bar;C:/baz;C:/foo/bar")
end
end
end
diff --git a/spec/unit/provider/package/aix_spec.rb b/spec/unit/provider/package/aix_spec.rb
index 6908b1288d..a39ab096c7 100644
--- a/spec/unit/provider/package/aix_spec.rb
+++ b/spec/unit/provider/package/aix_spec.rb
@@ -54,8 +54,8 @@ describe Chef::Provider::Package::Aix do
it "should raise an exception if a source is supplied but not found" do
allow(@provider).to receive(:popen4).and_return(@status)
allow(::File).to receive(:exists?).and_return(false)
- @provider.define_resource_requirements
@provider.load_current_resource
+ @provider.define_resource_requirements
expect { @provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Package)
end
diff --git a/spec/unit/provider/package/apt_spec.rb b/spec/unit/provider/package/apt_spec.rb
index e53fdc3f27..acf0707bbf 100644
--- a/spec/unit/provider/package/apt_spec.rb
+++ b/spec/unit/provider/package/apt_spec.rb
@@ -198,6 +198,11 @@ mpg123 1.12.1-0ubuntu1
it "raises an exception if a source is specified (CHEF-5113)" do
@new_resource.source "pluto"
+ expect(@provider).to receive(:shell_out!).with(
+ "apt-cache policy #{@new_resource.package_name}",
+ :timeout => @timeout
+ ).and_return(@shell_out)
+ @provider.load_current_resource
@provider.define_resource_requirements
expect(@provider).to receive(:shell_out!).with("apt-cache policy irssi", {:timeout=>900}).and_return(@shell_out)
expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package)
@@ -307,8 +312,7 @@ mpg123 1.12.1-0ubuntu1
end
it "should get the full path to the preseed response file" do
- expect(@provider).to receive(:get_preseed_file).with("irssi", "0.8.12-7").and_return("/tmp/irssi-0.8.12-7.seed")
- file = @provider.get_preseed_file("irssi", "0.8.12-7")
+ file = "/tmp/irssi-0.8.12-7.seed"
expect(@provider).to receive(:shell_out!).with(
"debconf-set-selections /tmp/irssi-0.8.12-7.seed",
diff --git a/spec/unit/provider/package/dpkg_spec.rb b/spec/unit/provider/package/dpkg_spec.rb
index fdd9e50c8e..154809f88c 100644
--- a/spec/unit/provider/package/dpkg_spec.rb
+++ b/spec/unit/provider/package/dpkg_spec.rb
@@ -88,8 +88,8 @@ describe Chef::Provider::Package::Dpkg do
it "should raise an exception if the source is not set but we are installing" do
@new_resource = Chef::Resource::Package.new("wget")
@provider.new_resource = @new_resource
- @provider.define_resource_requirements
@provider.load_current_resource
+ @provider.define_resource_requirements
expect { @provider.run_action(:install)}.to raise_error(Chef::Exceptions::Package)
end
diff --git a/spec/unit/provider/package/ips_spec.rb b/spec/unit/provider/package/ips_spec.rb
index 4e0afc46e9..342ac4c040 100644
--- a/spec/unit/provider/package/ips_spec.rb
+++ b/spec/unit/provider/package/ips_spec.rb
@@ -190,9 +190,8 @@ REMOTE
expect(@provider).to receive(:shell_out).with("pkg info #{@new_resource.package_name}").and_return(local)
expect(@provider).to receive(:shell_out!).with("pkg info -r #{@new_resource.package_name}").and_return(remote)
- @provider.load_current_resource
expect(@provider).to receive(:install_package).exactly(0).times
- @provider.action_install
+ @provider.run_action(:install)
end
context "when accept_license is true" do
diff --git a/spec/unit/provider/package/rpm_spec.rb b/spec/unit/provider/package/rpm_spec.rb
index 2aceee59a5..cd72044998 100644
--- a/spec/unit/provider/package/rpm_spec.rb
+++ b/spec/unit/provider/package/rpm_spec.rb
@@ -19,138 +19,186 @@
require 'spec_helper'
describe Chef::Provider::Package::Rpm do
- before(:each) do
- @node = Chef::Node.new
- @events = Chef::EventDispatch::Dispatcher.new
- @run_context = Chef::RunContext.new(@node, {}, @events)
-
- @new_resource = Chef::Resource::Package.new("ImageMagick-c++")
- @new_resource.source "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
-
- @provider = Chef::Provider::Package::Rpm.new(@new_resource, @run_context)
+ let(:provider) { Chef::Provider::Package::Rpm.new(new_resource, run_context) }
+ let(:node) { Chef::Node.new }
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
+ let(:run_context) { Chef::RunContext.new(node, {}, events) }
+ let(:new_resource) do
+ Chef::Resource::Package.new("ImageMagick-c++").tap do |resource|
+ resource.source "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
+ end
+ end
+ let(:exitstatus) { 0 }
+ let(:stdout) { String.new('') }
+ let(:status) { double('Process::Status', exitstatus: exitstatus, stdout: stdout) }
- @status = double("Status", :exitstatus => 0)
+ before(:each) do
allow(::File).to receive(:exists?).and_return(true)
+ allow(provider).to receive(:shell_out!).and_return(status)
end
describe "when determining the current state of the package" do
-
it "should create a current resource with the name of new_resource" do
- allow(@provider).to receive(:popen4).and_return(@status)
- @provider.load_current_resource
- expect(@provider.current_resource.name).to eq("ImageMagick-c++")
+ provider.load_current_resource
+ expect(provider.current_resource.name).to eq("ImageMagick-c++")
end
it "should set the current reource package name to the new resource package name" do
- allow(@provider).to receive(:popen4).and_return(@status)
- @provider.load_current_resource
- expect(@provider.current_resource.package_name).to eq('ImageMagick-c++')
+ provider.load_current_resource
+ expect(provider.current_resource.package_name).to eq('ImageMagick-c++')
end
it "should raise an exception if a source is supplied but not found" do
allow(::File).to receive(:exists?).and_return(false)
- expect { @provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
+ expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
end
- it "should get the source package version from rpm if provided" do
- @stdout = StringIO.new("ImageMagick-c++ 6.5.4.7-7.el6_5")
- expect(@provider).to receive(:popen4).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
- expect(@provider).to receive(:popen4).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' ImageMagick-c++").and_return(@status)
- @provider.load_current_resource
- expect(@provider.current_resource.package_name).to eq("ImageMagick-c++")
- expect(@provider.new_resource.version).to eq("6.5.4.7-7.el6_5")
- end
+ context "installation exists" do
+ let(:stdout) { "ImageMagick-c++ 6.5.4.7-7.el6_5" }
+
+ it "should get the source package version from rpm if provided" do
+ expect(provider).to receive(:shell_out!).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm").and_return(status)
+ expect(provider).to receive(:shell_out!).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' ImageMagick-c++").and_return(status)
+ provider.load_current_resource
+ expect(provider.current_resource.package_name).to eq("ImageMagick-c++")
+ expect(provider.new_resource.version).to eq("6.5.4.7-7.el6_5")
+ end
- it "should return the current version installed if found by rpm" do
- @stdout = StringIO.new("ImageMagick-c++ 6.5.4.7-7.el6_5")
- expect(@provider).to receive(:popen4).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm").and_return(@status)
- expect(@provider).to receive(:popen4).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' ImageMagick-c++").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
- @provider.load_current_resource
- expect(@provider.current_resource.version).to eq("6.5.4.7-7.el6_5")
+ it "should return the current version installed if found by rpm" do
+ expect(provider).to receive(:shell_out!).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm").and_return(status)
+ expect(provider).to receive(:shell_out!).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' ImageMagick-c++").and_return(status)
+ provider.load_current_resource
+ expect(provider.current_resource.version).to eq("6.5.4.7-7.el6_5")
+ end
end
- it "should raise an exception if the source is not set but we are installing" do
- new_resource = Chef::Resource::Package.new("ImageMagick-c++")
- provider = Chef::Provider::Package::Rpm.new(new_resource, @run_context)
- expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
+ context "source is uri formed" do
+ before(:each) do
+ allow(::File).to receive(:exists?).and_return(false)
+ end
+
+ %w(http HTTP https HTTPS ftp FTP).each do |scheme|
+ it "should accept uri formed source (#{scheme})" do
+ new_resource.source "#{scheme}://example.com/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
+ expect(provider.load_current_resource).not_to be_nil
+ end
+ end
+
+ %w(file FILE).each do |scheme|
+ it "should accept uri formed source (#{scheme})" do
+ new_resource.source "#{scheme}:///ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
+ expect(provider.load_current_resource).not_to be_nil
+ end
+ end
+
+ it "should raise an exception if an uri formed source is non-supported scheme" do
+ new_resource.source "foobar://example.com/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
+ expect(provider.load_current_resource).to be_nil
+ expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
+ end
end
- it "should raise an exception if rpm fails to run" do
- status = double("Status", :exitstatus => -1)
- allow(@provider).to receive(:popen4).and_return(status)
- expect { @provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
+ context "source is not defiend" do
+ let(:new_resource) { Chef::Resource::Package.new("ImageMagick-c++") }
+
+ it "should raise an exception if the source is not set but we are installing" do
+ expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
+ end
end
- it "should not detect the package name as version when not installed" do
- @status = double("Status", :exitstatus => -1)
- @stdout = StringIO.new("package openssh-askpass is not installed")
- @new_resource = Chef::Resource::Package.new("openssh-askpass")
- @new_resource.source 'openssh-askpass'
- @provider = Chef::Provider::Package::Rpm.new(@new_resource, @run_context)
- expect(@provider).to receive(:popen4).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' openssh-askpass").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
- expect(@provider).to receive(:popen4).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' openssh-askpass").and_return(@status)
- @provider.load_current_resource
- expect(@provider.current_resource.version).to be_nil
+ context "installation does not exist" do
+ let(:stdout) { String.new("package openssh-askpass is not installed") }
+ let(:exitstatus) { -1 }
+ let(:new_resource) do
+ Chef::Resource::Package.new("openssh-askpass").tap do |resource|
+ resource.source "openssh-askpass"
+ end
+ end
+
+ it "should raise an exception if rpm fails to run" do
+ allow(provider).to receive(:shell_out!).and_return(status)
+ expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "should not detect the package name as version when not installed" do
+ expect(provider).to receive(:shell_out!).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' openssh-askpass").and_return(status)
+ expect(provider).to receive(:shell_out!).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' openssh-askpass").and_return(status)
+ provider.load_current_resource
+ expect(provider.current_resource.version).to be_nil
+ end
end
end
describe "after the current resource is loaded" do
- before do
- @current_resource = Chef::Resource::Package.new("ImageMagick-c++")
- @provider.current_resource = @current_resource
+ let(:current_resource) { Chef::Resource::Package.new("ImageMagick-c++") }
+ let(:provider) do
+ Chef::Provider::Package::Rpm.new(new_resource, run_context).tap do |provider|
+ provider.current_resource = current_resource
+ end
end
describe "when installing or upgrading" do
it "should run rpm -i with the package source to install" do
- expect(@provider).to receive(:shell_out!).with("rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider.install_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
+ expect(provider).to receive(:shell_out!).with("rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.install_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
end
it "should run rpm -U with the package source to upgrade" do
- @current_resource.version("21.4-19.el5")
- expect(@provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider.upgrade_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
+ current_resource.version("21.4-19.el5")
+ expect(provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.upgrade_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
end
it "should install package if missing and set to upgrade" do
- @current_resource.version("ImageMagick-c++")
- expect(@provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider.upgrade_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
+ current_resource.version("ImageMagick-c++")
+ expect(provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.upgrade_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
end
- it "should install from a path when the package is a path and the source is nil" do
- @new_resource = Chef::Resource::Package.new("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider = Chef::Provider::Package::Rpm.new(@new_resource, @run_context)
- expect(@new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @current_resource = Chef::Resource::Package.new("ImageMagick-c++")
- @provider.current_resource = @current_resource
- expect(@provider).to receive(:shell_out!).with("rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider.install_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
+ context "allowing downgrade" do
+ let(:new_resource) { Chef::Resource::RpmPackage.new("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm") }
+ let(:current_resource) { Chef::Resource::RpmPackage.new("ImageMagick-c++") }
+
+ it "should run rpm -U --oldpackage with the package source to downgrade" do
+ new_resource.allow_downgrade(true)
+ current_resource.version("21.4-19.el5")
+ expect(provider).to receive(:shell_out!).with("rpm -U --oldpackage /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.upgrade_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
+ end
end
- it "should uprgrade from a path when the package is a path and the source is nil" do
- @new_resource = Chef::Resource::Package.new("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider = Chef::Provider::Package::Rpm.new(@new_resource, @run_context)
- expect(@new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @current_resource = Chef::Resource::Package.new("ImageMagick-c++")
- @current_resource.version("21.4-19.el5")
- @provider.current_resource = @current_resource
- expect(@provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider.upgrade_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
+ context "installing when the name is a path" do
+ let(:new_resource) { Chef::Resource::Package.new("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm") }
+ let(:current_resource) { Chef::Resource::Package.new("ImageMagick-c++") }
+
+ it "should install from a path when the package is a path and the source is nil" do
+ expect(new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.current_resource = current_resource
+ expect(provider).to receive(:shell_out!).with("rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.install_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
+ end
+
+ it "should uprgrade from a path when the package is a path and the source is nil" do
+ expect(new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ current_resource.version("21.4-19.el5")
+ provider.current_resource = current_resource
+ expect(provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.upgrade_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
+ end
end
it "installs with custom options specified in the resource" do
- @provider.candidate_version = '11'
- @new_resource.options("--dbpath /var/lib/rpm")
- expect(@provider).to receive(:shell_out!).with("rpm --dbpath /var/lib/rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider.install_package(@new_resource.name, @provider.candidate_version)
+ provider.candidate_version = '11'
+ new_resource.options("--dbpath /var/lib/rpm")
+ expect(provider).to receive(:shell_out!).with("rpm --dbpath /var/lib/rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.install_package(new_resource.name, provider.candidate_version)
end
end
describe "when removing the package" do
it "should run rpm -e to remove the package" do
- expect(@provider).to receive(:shell_out!).with("rpm -e ImageMagick-c++-6.5.4.7-7.el6_5")
- @provider.remove_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
+ expect(provider).to receive(:shell_out!).with("rpm -e ImageMagick-c++-6.5.4.7-7.el6_5")
+ provider.remove_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
end
end
end
diff --git a/spec/unit/provider/package/rubygems_spec.rb b/spec/unit/provider/package/rubygems_spec.rb
index b4960b2af3..b17c216ddd 100644
--- a/spec/unit/provider/package/rubygems_spec.rb
+++ b/spec/unit/provider/package/rubygems_spec.rb
@@ -371,6 +371,8 @@ describe Chef::Provider::Package::Rubygems do
# We choose detect omnibus via RbConfig::CONFIG['bindir'] in Chef::Provider::Package::Rubygems.new
allow(RbConfig::CONFIG).to receive(:[]).with('bindir').and_return("/usr/bin/ruby")
+ # Rubygems uses this interally
+ allow(RbConfig::CONFIG).to receive(:[]).with('arch').and_call_original
@provider = Chef::Provider::Package::Rubygems.new(@new_resource, @run_context)
end
@@ -379,7 +381,7 @@ describe Chef::Provider::Package::Rubygems do
it "target_version_already_installed? should return false so that we can search for candidates" do
@provider.load_current_resource
- expect(@provider.target_version_already_installed?).to be_falsey
+ expect(@provider.target_version_already_installed?(@provider.current_resource.version, @new_resource.version)).to be_falsey
end
end
@@ -469,6 +471,8 @@ describe Chef::Provider::Package::Rubygems do
it "determines the candidate version by querying the remote gem servers" do
@new_resource.source('http://mygems.example.com')
+ @provider.load_current_resource
+ @provider.current_resource.version('0.0.1')
version = Gem::Version.new(@spec_version)
expect(@provider.gem_env).to receive(:candidate_version_from_remote).
with(Gem::Dependency.new('rspec-core', @spec_version), "http://mygems.example.com").
@@ -478,8 +482,9 @@ describe Chef::Provider::Package::Rubygems do
it "parses the gem's specification if the requested source is a file" do
@new_resource.package_name('chef-integration-test')
- @new_resource.version('>= 0')
@new_resource.source(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
+ @new_resource.version('>= 0')
+ @provider.load_current_resource
expect(@provider.candidate_version).to eq('0.1.0')
end
@@ -496,20 +501,23 @@ describe Chef::Provider::Package::Rubygems do
describe "in the current gem environment" do
it "installs the gem via the gems api when no explicit options are used" do
expect(@provider.gem_env).to receive(:install).with(@gem_dep, :sources => nil)
- expect(@provider.action_install).to be_truthy
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
it "installs the gem via the gems api when a remote source is provided" do
@new_resource.source('http://gems.example.org')
sources = ['http://gems.example.org']
expect(@provider.gem_env).to receive(:install).with(@gem_dep, :sources => sources)
- expect(@provider.action_install).to be_truthy
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
it "installs the gem from file via the gems api when no explicit options are used" do
@new_resource.source(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
expect(@provider.gem_env).to receive(:install).with(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
- expect(@provider.action_install).to be_truthy
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
it "installs the gem from file via the gems api when the package is a path and the source is nil" do
@@ -518,7 +526,8 @@ describe Chef::Provider::Package::Rubygems do
@provider.current_resource = @current_resource
expect(@new_resource.source).to eq(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
expect(@provider.gem_env).to receive(:install).with(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
- expect(@provider.action_install).to be_truthy
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
# this catches 'gem_package "foo"' when "./foo" is a file in the cwd, and instead of installing './foo' it fetches the remote gem
@@ -526,28 +535,35 @@ describe Chef::Provider::Package::Rubygems do
allow(::File).to receive(:exists?).and_return(true)
@new_resource.package_name('rspec-core')
expect(@provider.gem_env).to receive(:install).with(@gem_dep, :sources => nil)
- expect(@provider.action_install).to be_truthy
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
it "installs the gem by shelling out when options are provided as a String" do
@new_resource.options('-i /alt/install/location')
expected ="gem install rspec-core -q --no-rdoc --no-ri -v \"#{@spec_version}\" -i /alt/install/location"
expect(@provider).to receive(:shell_out!).with(expected, :env => nil)
- expect(@provider.action_install).to be_truthy
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
- it "installs the gem by shelling out when options are provided but no version is given" do
- @new_resource.options('-i /alt/install/location')
- @new_resource.version('')
- expected ="gem install \"rspec-core\" -q --no-rdoc --no-ri -i /alt/install/location"
- expect(@provider).to receive(:shell_out!).with(expected, :env => nil)
- expect(@provider.action_install).to be_truthy
+ context "when no version is given" do
+ let(:target_version) { nil }
+
+ it "installs the gem by shelling out when options are provided but no version is given" do
+ @new_resource.options('-i /alt/install/location')
+ expected ="gem install rspec-core -q --no-rdoc --no-ri -v \"#{@provider.candidate_version}\" -i /alt/install/location"
+ expect(@provider).to receive(:shell_out!).with(expected, :env => nil)
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
+ end
end
it "installs the gem via the gems api when options are given as a Hash" do
@new_resource.options(:install_dir => '/alt/install/location')
expect(@provider.gem_env).to receive(:install).with(@gem_dep, :sources => nil, :install_dir => '/alt/install/location')
- expect(@provider.action_install).to be_truthy
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
describe "at a specific version" do
@@ -557,24 +573,25 @@ describe Chef::Provider::Package::Rubygems do
it "installs the gem via the gems api" do
expect(@provider.gem_env).to receive(:install).with(@gem_dep, :sources => nil)
- expect(@provider.action_install).to be_truthy
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
end
describe "at version specified with comparison operator" do
it "skips install if current version satisifies requested version" do
- allow(@current_resource).to receive(:version).and_return("2.3.3")
- allow(@new_resource).to receive(:version).and_return(">=2.3.0")
+ @current_resource.version("2.3.3")
+ @new_resource.version(">=2.3.0")
expect(@provider.gem_env).not_to receive(:install)
- @provider.action_install
+ @provider.run_action(:install)
end
it "allows user to specify gem version with fuzzy operator" do
- allow(@current_resource).to receive(:version).and_return("2.3.3")
- allow(@new_resource).to receive(:version).and_return("~>2.3.0")
+ @current_resource.version("2.3.3")
+ @new_resource.version("~>2.3.0")
expect(@provider.gem_env).not_to receive(:install)
- @provider.action_install
+ @provider.run_action(:install)
end
end
end
@@ -583,7 +600,8 @@ describe Chef::Provider::Package::Rubygems do
it "installs the gem by shelling out to gem install" do
@new_resource.gem_binary('/usr/weird/bin/gem')
expect(@provider).to receive(:shell_out!).with("/usr/weird/bin/gem install rspec-core -q --no-rdoc --no-ri -v \"#{@spec_version}\"", :env=>nil)
- expect(@provider.action_install).to be_truthy
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
it "installs the gem from file by shelling out to gem install" do
@@ -591,7 +609,8 @@ describe Chef::Provider::Package::Rubygems do
@new_resource.source(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
@new_resource.version('>= 0')
expect(@provider).to receive(:shell_out!).with("/usr/weird/bin/gem install #{CHEF_SPEC_DATA}/gems/chef-integration-test-0.1.0.gem -q --no-rdoc --no-ri -v \">= 0\"", :env=>nil)
- expect(@provider.action_install).to be_truthy
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
it "installs the gem from file by shelling out to gem install when the package is a path and the source is nil" do
@@ -602,7 +621,8 @@ describe Chef::Provider::Package::Rubygems do
@new_resource.version('>= 0')
expect(@new_resource.source).to eq(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
expect(@provider).to receive(:shell_out!).with("/usr/weird/bin/gem install #{CHEF_SPEC_DATA}/gems/chef-integration-test-0.1.0.gem -q --no-rdoc --no-ri -v \">= 0\"", :env=>nil)
- expect(@provider.action_install).to be_truthy
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
end
diff --git a/spec/unit/provider/package/solaris_spec.rb b/spec/unit/provider/package/solaris_spec.rb
index 8438202576..332fa9db1a 100644
--- a/spec/unit/provider/package/solaris_spec.rb
+++ b/spec/unit/provider/package/solaris_spec.rb
@@ -64,8 +64,8 @@ PKGINFO
it "should raise an exception if a source is supplied but not found" do
allow(@provider).to receive(:popen4).and_return(@status)
allow(::File).to receive(:exists?).and_return(false)
- @provider.define_resource_requirements
@provider.load_current_resource
+ @provider.define_resource_requirements
expect { @provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Package)
end
diff --git a/spec/unit/provider/package/yum_spec.rb b/spec/unit/provider/package/yum_spec.rb
index 0d2a44f3ae..e5e32bc9c0 100644
--- a/spec/unit/provider/package/yum_spec.rb
+++ b/spec/unit/provider/package/yum_spec.rb
@@ -337,9 +337,9 @@ describe Chef::Provider::Package::Yum do
@provider.load_current_resource
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
- "yum -d0 -e0 -y install emacs-1.0"
+ "yum -d0 -e0 -y install cups-1.2.4-11.19.el5"
)
- @provider.install_package("emacs", "1.0")
+ @provider.install_package("cups", "1.2.4-11.19.el5")
end
it "should run yum localinstall if given a path to an rpm" do
@@ -366,14 +366,14 @@ describe Chef::Provider::Package::Yum do
allow(@new_resource).to receive(:arch).and_return("i386")
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
- "yum -d0 -e0 -y install emacs-21.4-20.el5.i386"
+ "yum -d0 -e0 -y install cups-1.2.4-11.19.el5.i386"
)
- @provider.install_package("emacs", "21.4-20.el5")
+ @provider.install_package("cups", "1.2.4-11.19.el5")
end
it "installs the package with the options given in the resource" do
@provider.load_current_resource
- @provider.candidate_version = '11'
+ allow(@provider).to receive(:candidate_version).and_return('11')
allow(@new_resource).to receive(:options).and_return("--disablerepo epmd")
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
@@ -467,10 +467,10 @@ describe Chef::Provider::Package::Yum do
@provider.load_current_resource
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
- "yum -d0 -e0 -y install emacs-1.0"
+ "yum -d0 -e0 -y install cups-1.2.4-11.15.el5"
)
expect(@yum_cache).to receive(:reload).once
- @provider.install_package("emacs", "1.0")
+ @provider.install_package("cups", "1.2.4-11.15.el5")
end
it "should run yum install then not flush the cache if :after is false" do
@@ -478,17 +478,17 @@ describe Chef::Provider::Package::Yum do
@provider.load_current_resource
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
- "yum -d0 -e0 -y install emacs-1.0"
+ "yum -d0 -e0 -y install cups-1.2.4-11.15.el5"
)
expect(@yum_cache).not_to receive(:reload)
- @provider.install_package("emacs", "1.0")
+ @provider.install_package("cups", "1.2.4-11.15.el5")
end
end
describe "when upgrading a package" do
it "should run yum install if the package is installed and a version is given" do
@provider.load_current_resource
- @provider.candidate_version = '11'
+ allow(@provider).to receive(:candidate_version).and_return('11')
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
"yum -d0 -e0 -y install cups-11"
@@ -499,7 +499,7 @@ describe Chef::Provider::Package::Yum do
it "should run yum install if the package is not installed" do
@provider.load_current_resource
@current_resource = Chef::Resource::Package.new('cups')
- @provider.candidate_version = '11'
+ allow(@provider).to receive(:candidate_version).and_return('11')
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
"yum -d0 -e0 -y install cups-11"
@@ -528,42 +528,41 @@ describe Chef::Provider::Package::Yum do
# Test our little workaround, some crossover into Chef::Provider::Package territory
it "should call action_upgrade in the parent if the current resource version is nil" do
allow(@yum_cache).to receive(:installed_version).and_return(nil)
- @provider.load_current_resource
@current_resource = Chef::Resource::Package.new('cups')
- @provider.candidate_version = '11'
+ allow(@provider).to receive(:candidate_version).and_return('11')
expect(@provider).to receive(:upgrade_package).with(
"cups",
"11"
)
- @provider.action_upgrade
+ @provider.run_action(:upgrade)
end
it "should call action_upgrade in the parent if the candidate version is nil" do
@provider.load_current_resource
@current_resource = Chef::Resource::Package.new('cups')
- @provider.candidate_version = nil
+ allow(@provider).to receive(:candidate_version).and_return(nil)
expect(@provider).not_to receive(:upgrade_package)
- @provider.action_upgrade
+ @provider.run_action(:upgrade)
end
it "should call action_upgrade in the parent if the candidate is newer" do
@provider.load_current_resource
@current_resource = Chef::Resource::Package.new('cups')
- @provider.candidate_version = '11'
+ allow(@provider).to receive(:candidate_version).and_return('11')
expect(@provider).to receive(:upgrade_package).with(
"cups",
"11"
)
- @provider.action_upgrade
+ @provider.run_action(:upgrade)
end
it "should not call action_upgrade in the parent if the candidate is older" do
allow(@yum_cache).to receive(:installed_version).and_return("12")
@provider.load_current_resource
@current_resource = Chef::Resource::Package.new('cups')
- @provider.candidate_version = '11'
+ allow(@provider).to receive(:candidate_version).and_return('11')
expect(@provider).not_to receive(:upgrade_package)
- @provider.action_upgrade
+ @provider.run_action(:upgrade)
end
end
@@ -1861,3 +1860,103 @@ EOF
end
end
+
+describe "Chef::Provider::Package::Yum - Multi" do
+ before(:each) do
+ @node = Chef::Node.new
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+ @new_resource = Chef::Resource::Package.new(['cups', 'vim'])
+ @status = double("Status", :exitstatus => 0)
+ @yum_cache = double(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => 'XXXX',
+ :candidate_version => 'YYYY',
+ :package_available? => true,
+ :version_available? => true,
+ :allow_multi_install => [ 'kernel' ],
+ :package_repository => 'base',
+ :disable_extra_repo_control => true
+ )
+ allow(Chef::Provider::Package::Yum::YumCache).to receive(:instance).and_return(@yum_cache)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @pid = double("PID")
+ end
+
+ describe "when loading the current system state" do
+ it "should create a current resource with the name of the new_resource" do
+ @provider.load_current_resource
+ expect(@provider.current_resource.name).to eq('cups, vim')
+ end
+
+ it "should set the current resources package name to the new resources package name" do
+ @provider.load_current_resource
+ expect(@provider.current_resource.package_name).to eq(['cups', 'vim'])
+ end
+
+ it "should set the installed version to nil on the current resource if no installed package" do
+ allow(@yum_cache).to receive(:installed_version).and_return(nil)
+ @provider.load_current_resource
+ expect(@provider.current_resource.version).to eq([nil, nil])
+ end
+
+ it "should set the installed version if yum has one" do
+ allow(@yum_cache).to receive(:installed_version).with('cups', nil).and_return('1.2.4-11.18.el5')
+ allow(@yum_cache).to receive(:installed_version).with('vim', nil).and_return('1.0')
+ allow(@yum_cache).to receive(:candidate_version).with('cups', nil).and_return('1.2.4-11.18.el5_2.3')
+ allow(@yum_cache).to receive(:candidate_version).with('vim', nil).and_return('1.5')
+ @provider.load_current_resource
+ expect(@provider.current_resource.version).to eq(['1.2.4-11.18.el5', '1.0'])
+ end
+
+ it "should set the candidate version if yum info has one" do
+ allow(@yum_cache).to receive(:installed_version).with('cups', nil).and_return('1.2.4-11.18.el5')
+ allow(@yum_cache).to receive(:installed_version).with('vim', nil).and_return('1.0')
+ allow(@yum_cache).to receive(:candidate_version).with('cups', nil).and_return('1.2.4-11.18.el5_2.3')
+ allow(@yum_cache).to receive(:candidate_version).with('vim', nil).and_return('1.5')
+ @provider.load_current_resource
+ expect(@provider.candidate_version).to eql(['1.2.4-11.18.el5_2.3', '1.5'])
+ end
+
+ it "should return the current resouce" do
+ expect(@provider.load_current_resource).to eql(@provider.current_resource)
+ end
+ end
+
+ describe "when installing a package" do
+ it "should run yum install with the package name and version" do
+ @provider.load_current_resource
+ allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
+ allow(@yum_cache).to receive(:installed_version).with('cups', nil).and_return('1.2.4-11.18.el5')
+ allow(@yum_cache).to receive(:installed_version).with('vim', nil).and_return('0.9')
+ expect(@provider).to receive(:yum_command).with(
+ "yum -d0 -e0 -y install cups-1.2.4-11.19.el5 vim-1.0"
+ )
+ @provider.install_package(["cups", "vim"], ["1.2.4-11.19.el5", '1.0'])
+ end
+
+ it "should run yum install with the package name, version and arch" do
+ @provider.load_current_resource
+ allow(@new_resource).to receive(:arch).and_return("i386")
+ allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
+ expect(@provider).to receive(:yum_command).with(
+ "yum -d0 -e0 -y install cups-1.2.4-11.19.el5.i386 vim-1.0.i386"
+ )
+ @provider.install_package(["cups", "vim"], ["1.2.4-11.19.el5", "1.0"])
+ end
+
+ it "installs the package with the options given in the resource" do
+ @provider.load_current_resource
+ allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
+ allow(@yum_cache).to receive(:installed_version).with('cups', nil).and_return('1.2.4-11.18.el5')
+ allow(@yum_cache).to receive(:installed_version).with('vim', nil).and_return('0.9')
+ expect(@provider).to receive(:yum_command).with(
+ "yum -d0 -e0 -y --disablerepo epmd install cups-1.2.4-11.19.el5 vim-1.0"
+ )
+ allow(@new_resource).to receive(:options).and_return("--disablerepo epmd")
+ @provider.install_package(["cups", "vim"], ["1.2.4-11.19.el5", '1.0'])
+ end
+ end
+end
diff --git a/spec/unit/provider/package_spec.rb b/spec/unit/provider/package_spec.rb
index 2aeaf717e6..1633d18f9d 100644
--- a/spec/unit/provider/package_spec.rb
+++ b/spec/unit/provider/package_spec.rb
@@ -152,7 +152,7 @@ describe Chef::Provider::Package do
it "should print the word 'uninstalled' if there was no original version" do
allow(@current_resource).to receive(:version).and_return(nil)
- expect(Chef::Log).to receive(:info).with("package[emacs] upgraded from uninstalled to 1.0")
+ expect(Chef::Log).to receive(:info).with("package[emacs] upgraded emacs to 1.0")
@provider.run_action(:upgrade)
expect(@new_resource).to be_updated_by_last_action
end
@@ -425,3 +425,277 @@ describe Chef::Provider::Package do
end
end
+
+describe "Chef::Provider::Package - Multi" do
+ before do
+ @node = Chef::Node.new
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+ @new_resource = Chef::Resource::Package.new(['emacs', 'vi'])
+ @current_resource = Chef::Resource::Package.new(['emacs', 'vi'])
+ @provider = Chef::Provider::Package.new(@new_resource, @run_context)
+ @provider.current_resource = @current_resource
+ @provider.candidate_version = ['1.0', '6.2']
+ end
+
+ describe "when installing multiple packages" do
+ before(:each) do
+ @provider.current_resource = @current_resource
+ allow(@provider).to receive(:install_package).and_return(true)
+ end
+
+ it "installs the candidate versions when none are installed" do
+ expect(@provider).to receive(:install_package).with(
+ ["emacs", "vi"],
+ ["1.0", "6.2"]
+ ).and_return(true)
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated
+ end
+
+ it "installs the candidate versions when some are installed" do
+ expect(@provider).to receive(:install_package).with(
+ [ 'vi' ],
+ [ '6.2' ]
+ ).and_return(true)
+ @current_resource.version(['1.0', nil])
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated
+ end
+
+ it "installs the specified version when some are out of date" do
+ @current_resource.version(['1.0', '6.2'])
+ @new_resource.version(['1.0', '6.1'])
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated
+ end
+
+ it "does not install any version if all are installed at the right version" do
+ @current_resource.version(['1.0', '6.2'])
+ @new_resource.version(['1.0', '6.2'])
+ @provider.run_action(:install)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+
+ it "does not install any version if all are installed, and no version was specified" do
+ @current_resource.version(['1.0', '6.2'])
+ @provider.run_action(:install)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+
+ it "raises an exception if both are not installed and no caondidates are available" do
+ @current_resource.version([nil, nil])
+ @provider.candidate_version = [nil, nil]
+ expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "raises an exception if one is not installed and no candidates are available" do
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = ['1.0', nil]
+ expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "does not raise an exception if the packages are installed or have a candidate" do
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = [nil, '6.2']
+ expect { @provider.run_action(:install) }.not_to raise_error
+ end
+
+ it "raises an exception if an explicit version is asked for, an old version is installed, but no candidate" do
+ @new_resource.version ['1.0', '6.2']
+ @current_resource.version(['1.0', '6.1'])
+ @provider.candidate_version = ['1.0', nil]
+ expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "does not raise an exception if an explicit version is asked for, and is installed, but no candidate" do
+ @new_resource.version ['1.0', '6.2']
+ @current_resource.version(['1.0', '6.2'])
+ @provider.candidate_version = ['1.0', nil]
+ expect { @provider.run_action(:install) }.not_to raise_error
+ end
+
+ it "raise an exception if an explicit version is asked for, and is not installed, and no candidate" do
+ @new_resource.version ['1.0', '6.2']
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = ['1.0', nil]
+ expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "does not raise an exception if an explicit version is asked for, and is not installed, and there is a candidate" do
+ @new_resource.version ['1.0', '6.2']
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = ['1.0', '6.2']
+ expect { @provider.run_action(:install) }.not_to raise_error
+ end
+ end
+
+ describe "when upgrading multiple packages" do
+ before(:each) do
+ @provider.current_resource = @current_resource
+ allow(@provider).to receive(:upgrade_package).and_return(true)
+ end
+
+ it "should upgrade the package if the current versions are not the candidate version" do
+ @current_resource.version ['0.9', '6.1']
+ expect(@provider).to receive(:upgrade_package).with(
+ @new_resource.package_name,
+ @provider.candidate_version
+ ).and_return(true)
+ @provider.run_action(:upgrade)
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should upgrade the package if some of current versions are not the candidate versions" do
+ @current_resource.version ['1.0', '6.1']
+ expect(@provider).to receive(:upgrade_package).with(
+ ["vi"],
+ ["6.2"]
+ ).and_return(true)
+ @provider.run_action(:upgrade)
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should not install the package if the current versions are the candidate version" do
+ @current_resource.version ['1.0', '6.2']
+ expect(@provider).not_to receive(:upgrade_package)
+ @provider.run_action(:upgrade)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+
+ it "should raise an exception if both are not installed and no caondidates are available" do
+ @current_resource.version([nil, nil])
+ @provider.candidate_version = [nil, nil]
+ expect { @provider.run_action(:upgrade) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "should raise an exception if one is not installed and no candidates are available" do
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = ['1.0', nil]
+ expect { @provider.run_action(:upgrade) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "should not raise an exception if the packages are installed or have a candidate" do
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = [nil, '6.2']
+ expect { @provider.run_action(:upgrade) }.not_to raise_error
+ end
+
+ it "should not raise an exception if the packages are installed or have a candidate" do
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = [nil, '6.2']
+ expect { @provider.run_action(:upgrade) }.not_to raise_error
+ end
+ end
+
+ describe "When removing multiple packages " do
+ before(:each) do
+ allow(@provider).to receive(:remove_package).and_return(true)
+ @current_resource.version ['1.0', '6.2']
+ end
+
+ it "should remove the packages if all are installed" do
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:remove_package).with(['emacs', 'vi'], nil)
+ @provider.run_action(:remove)
+ expect(@new_resource).to be_updated
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should remove the packages if some are installed" do
+ @current_resource.version ['1.0', nil]
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:remove_package).with(['emacs', 'vi'], nil)
+ @provider.run_action(:remove)
+ expect(@new_resource).to be_updated
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should remove the packages at a specific version if they are installed at that version" do
+ @new_resource.version ['1.0', '6.2']
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:remove_package).with(['emacs', 'vi'], ['1.0', '6.2'])
+ @provider.run_action(:remove)
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should remove the packages at a specific version any are is installed at that version" do
+ @new_resource.version ['0.5', '6.2']
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:remove_package).with(['emacs', 'vi'], ['0.5', '6.2'])
+ @provider.run_action(:remove)
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should not remove the packages at a specific version if they are not installed at that version" do
+ @new_resource.version ['0.5', '6.0']
+ expect(@provider).not_to be_removing_package
+ expect(@provider).not_to receive(:remove_package)
+ @provider.run_action(:remove)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+
+ it "should not remove the packages if they are not installed" do
+ expect(@provider).not_to receive(:remove_package)
+ allow(@current_resource).to receive(:version).and_return(nil)
+ @provider.run_action(:remove)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+
+ end
+
+ describe "When purging multiple packages " do
+ before(:each) do
+ allow(@provider).to receive(:purge_package).and_return(true)
+ @current_resource.version ['1.0', '6.2']
+ end
+
+ it "should purge the packages if all are installed" do
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:purge_package).with(['emacs', 'vi'], nil)
+ @provider.run_action(:purge)
+ expect(@new_resource).to be_updated
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should purge the packages if some are installed" do
+ @current_resource.version ['1.0', nil]
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:purge_package).with(['emacs', 'vi'], nil)
+ @provider.run_action(:purge)
+ expect(@new_resource).to be_updated
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should purge the packages at a specific version if they are installed at that version" do
+ @new_resource.version ['1.0', '6.2']
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:purge_package).with(['emacs', 'vi'], ['1.0', '6.2'])
+ @provider.run_action(:purge)
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should purge the packages at a specific version any are is installed at that version" do
+ @new_resource.version ['0.5', '6.2']
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:purge_package).with(['emacs', 'vi'], ['0.5', '6.2'])
+ @provider.run_action(:purge)
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should not purge the packages at a specific version if they are not installed at that version" do
+ @new_resource.version ['0.5', '6.0']
+ expect(@provider).not_to be_removing_package
+ expect(@provider).not_to receive(:purge_package)
+ @provider.run_action(:purge)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+
+ it "should not purge the packages if they are not installed" do
+ expect(@provider).not_to receive(:purge_package)
+ allow(@current_resource).to receive(:version).and_return(nil)
+ @provider.run_action(:purge)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+ end
+end
diff --git a/spec/unit/provider/package_spec.rbe b/spec/unit/provider/package_spec.rbe
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/spec/unit/provider/package_spec.rbe
diff --git a/spec/unit/provider/service/freebsd_service_spec.rb b/spec/unit/provider/service/freebsd_service_spec.rb
index 91d2d8e063..5a55425d87 100644
--- a/spec/unit/provider/service/freebsd_service_spec.rb
+++ b/spec/unit/provider/service/freebsd_service_spec.rb
@@ -580,6 +580,13 @@ EOF
expect(provider).not_to receive(:write_rc_conf)
provider.enable_service
end
+
+ it "should remove commented out versions of it being enabled" do
+ allow(current_resource).to receive(:enabled).and_return(false)
+ expect(provider).to receive(:read_rc_conf).and_return([ "foo", "bar", "\# #{new_resource.service_name}_enable=\"YES\"", "\# #{new_resource.service_name}_enable=\"NO\""])
+ expect(provider).to receive(:write_rc_conf).with(["foo", "bar", "#{new_resource.service_name}_enable=\"YES\""])
+ provider.enable_service()
+ end
end
describe Chef::Provider::Service::Freebsd, "disable_service" do
@@ -607,5 +614,12 @@ EOF
expect(provider).not_to receive(:write_rc_conf)
provider.disable_service()
end
+
+ it "should remove commented out versions of it being disabled or enabled" do
+ allow(current_resource).to receive(:enabled).and_return(true)
+ expect(provider).to receive(:read_rc_conf).and_return([ "foo", "bar", "\# #{new_resource.service_name}_enable=\"YES\"", "\# #{new_resource.service_name}_enable=\"NO\""])
+ expect(provider).to receive(:write_rc_conf).with(["foo", "bar", "#{new_resource.service_name}_enable=\"NO\""])
+ provider.disable_service()
+ end
end
end
diff --git a/spec/unit/provider/service/openbsd_service_spec.rb b/spec/unit/provider/service/openbsd_service_spec.rb
new file mode 100644
index 0000000000..1b5206470e
--- /dev/null
+++ b/spec/unit/provider/service/openbsd_service_spec.rb
@@ -0,0 +1,543 @@
+#
+# Author:: Bryan McLellan (btm@loftninjas.org)
+# Author:: Scott Bonds (scott@ggr.com)
+# Copyright:: Copyright (c) 2009 Bryan McLellan
+# Copyright:: Copyright (c) 2014 Scott Bonds
+# 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'
+
+class Chef::Provider::Service::Openbsd
+ public :builtin_service_enable_variable_name
+ public :determine_enabled_status!
+ public :determine_current_status!
+ public :is_enabled?
+ attr_accessor :rc_conf, :rc_conf_local
+end
+
+describe Chef::Provider::Service::Openbsd do
+ let(:node) do
+ node = Chef::Node.new
+ node.automatic_attrs[:command] = {:ps => "ps -ax"}
+ node
+ end
+
+ let(:new_resource) do
+ new_resource = Chef::Resource::Service.new("sndiod")
+ new_resource.pattern("sndiod")
+ new_resource.supports({:status => false})
+ new_resource
+ end
+
+ let(:current_resource) do
+ current_resource = Chef::Resource::Service.new("sndiod")
+ current_resource
+ end
+
+ let(:provider) do
+ events = Chef::EventDispatch::Dispatcher.new
+ run_context = Chef::RunContext.new(node, {}, events)
+ allow(::File).to receive(:read).with('/etc/rc.conf').and_return('')
+ allow(::File).to receive(:read).with('/etc/rc.conf.local').and_return('')
+ provider = Chef::Provider::Service::Openbsd.new(new_resource,run_context)
+ provider.action = :start
+ provider
+ end
+
+ before do
+ allow(Chef::Resource::Service).to receive(:new).and_return(current_resource)
+ end
+
+ def stub_etc_rcd_script
+ allow(::File).to receive(:exist?).and_return(false)
+ expect(::File).to receive(:exist?).with("/etc/rc.d/#{new_resource.service_name}").and_return(true)
+ end
+
+ def run_load_current_resource
+ stub_etc_rcd_script
+ provider.load_current_resource
+ end
+
+ describe Chef::Provider::Service::Openbsd, "initialize" do
+ it "should find /etc/rc.d init scripts" do
+ stub_etc_rcd_script
+ expect(provider.init_command).to eql "/etc/rc.d/sndiod"
+ end
+
+ it "should set init_command to nil if it can't find anything" do
+ expect(::File).to receive(:exist?).with('/etc/rc.d/sndiod').and_return(false)
+ expect(provider.init_command).to be nil
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "determine_current_status!" do
+ before do
+ stub_etc_rcd_script
+ provider.current_resource = current_resource
+ current_resource.service_name(new_resource.service_name)
+ end
+
+ context "when a status command has been specified" do
+ let(:status) { double(:stdout => "", :exitstatus => 0) }
+
+ before do
+ new_resource.status_command("/bin/chefhasmonkeypants status")
+ end
+
+ it "should run the services status command if one has been specified" do
+ expect(provider).to receive(:shell_out).with("/bin/chefhasmonkeypants status").and_return(status)
+ provider.determine_current_status!
+ end
+ end
+
+ context "when the service supports status" do
+ let(:status) { double(:stdout => "", :exitstatus => 0) }
+
+ before do
+ new_resource.supports({:status => true})
+ end
+
+ it "should run '/etc/rc.d/service_name status'" do
+ expect(provider).to receive(:shell_out).with("/etc/rc.d/#{new_resource.service_name} check").and_return(status)
+ provider.determine_current_status!
+ end
+
+ it "should set running to true if the status command returns 0" do
+ expect(provider).to receive(:shell_out).with("/etc/rc.d/#{new_resource.service_name} check").and_return(status)
+ provider.determine_current_status!
+ expect(current_resource.running).to be true
+ end
+
+ it "should set running to false if the status command returns anything except 0" do
+ expect(provider).to receive(:shell_out).with("/etc/rc.d/#{new_resource.service_name} check").and_raise(Mixlib::ShellOut::ShellCommandFailed)
+ provider.determine_current_status!
+ expect(current_resource.running).to be false
+ end
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "determine_enabled_status!" do
+ before do
+ stub_etc_rcd_script
+ provider.current_resource = current_resource
+ current_resource.service_name(new_resource.service_name)
+
+ allow(provider).to receive(:service_enable_variable_name).and_return("#{new_resource.service_name}_enable")
+ end
+
+ context "when the service is builtin" do
+ before do
+ expect(::File).to receive(:open).with("/etc/rc.d/#{new_resource.service_name}")
+ provider.rc_conf = "#{provider.builtin_service_enable_variable_name}=NO"
+ provider.rc_conf_local = lines.join("\n")
+ end
+
+ %w{YES Yes yes yEs YeS}.each do |setting|
+ context "when the enable variable is set to #{setting}" do
+ let(:lines) { [ %Q{#{provider.builtin_service_enable_variable_name}="#{setting}"} ] }
+ it "sets enabled to true" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be true
+ end
+ end
+ end
+
+ %w{No NO no nO None NONE none nOnE}.each do |setting|
+ context "when the enable variable is set to #{setting}" do
+ let(:lines) { [ %Q{#{provider.builtin_service_enable_variable_name}="#{setting}"} ] }
+ it "sets enabled to false" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+ end
+
+ context "when the enable variable is garbage" do
+ let(:lines) { [ %Q{#{provider.builtin_service_enable_variable_name}_enable="alskdjflasdkjflakdfj"} ] }
+ it "sets enabled to false" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+
+ context "when the enable variable partial matches (left) some other service and we are disabled" do
+ let(:lines) { [
+ %Q{thing_#{provider.builtin_service_enable_variable_name}="YES"},
+ %Q{#{provider.builtin_service_enable_variable_name}="NO"},
+ ] }
+ it "sets enabled based on the exact match (false)" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+
+ context "when the enable variable partial matches (right) some other service and we are disabled" do
+ let(:lines) { [
+ %Q{#{provider.builtin_service_enable_variable_name}_thing="YES"},
+ %Q{#{provider.builtin_service_enable_variable_name}},
+ ] }
+ it "sets enabled based on the exact match (false)" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+
+ context "when the enable variable partial matches (left) some other disabled service and we are enabled" do
+ let(:lines) { [
+ %Q{thing_#{provider.builtin_service_enable_variable_name}="NO"},
+ %Q{#{provider.builtin_service_enable_variable_name}="YES"},
+ ] }
+ it "sets enabled based on the exact match (true)" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be true
+ end
+ end
+
+ context "when the enable variable partial matches (right) some other disabled service and we are enabled" do
+ let(:lines) { [
+ %Q{#{provider.builtin_service_enable_variable_name}_thing="NO"},
+ %Q{#{provider.builtin_service_enable_variable_name}="YES"},
+ ] }
+ it "sets enabled based on the exact match (true)" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be true
+ end
+ end
+
+ context "when the enable variable only partial matches (left) some other enabled service" do
+ let(:lines) { [ %Q{thing_#{provider.builtin_service_enable_variable_name}_enable="YES"} ] }
+ it "sets enabled to false" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+
+ context "when the enable variable only partial matches (right) some other enabled service" do
+ let(:lines) { [ %Q{#{provider.builtin_service_enable_variable_name}_thing_enable="YES"} ] }
+ it "sets enabled to false" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+
+ context "when nothing matches" do
+ let(:lines) { [] }
+ it "sets enabled to true" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "load_current_resource" do
+ before(:each) do
+ stub_etc_rcd_script
+ expect(provider).to receive(:determine_current_status!)
+ current_resource.running(false)
+ allow(provider).to receive(:service_enable_variable_name).and_return "#{new_resource.service_name}_enable"
+ expect(::File).to receive(:open).with("/etc/rc.d/#{new_resource.service_name}")
+ end
+
+ it "should create a current resource with the name of the new resource" do
+ expect(Chef::Resource::Service).to receive(:new).and_return(current_resource)
+ provider.load_current_resource
+ end
+
+ it "should set the current resources service name to the new resources service name" do
+ provider.load_current_resource
+ expect(current_resource.service_name).to eq(new_resource.service_name)
+ end
+
+ it "should return the current resource" do
+ expect(provider.load_current_resource).to eql(current_resource)
+ end
+
+ end
+
+ context "when testing actions" do
+ before(:each) do
+ stub_etc_rcd_script
+ expect(provider).to receive(:determine_current_status!)
+ current_resource.running(false)
+ expect(provider).to receive(:determine_enabled_status!)
+ current_resource.enabled(false)
+ provider.load_current_resource
+ end
+
+ describe Chef::Provider::Service::Openbsd, "start_service" do
+ it "should call the start command if one is specified" do
+ new_resource.start_command("/etc/rc.d/chef startyousillysally")
+ expect(provider).to receive(:shell_out_with_systems_locale!).with("/etc/rc.d/chef startyousillysally")
+ provider.start_service()
+ end
+
+ it "should call '/usr/local/etc/rc.d/service_name start' if no start command is specified" do
+ expect(provider).to receive(:shell_out_with_systems_locale!).with("/etc/rc.d/#{new_resource.service_name} start")
+ provider.start_service()
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "stop_service" do
+ it "should call the stop command if one is specified" do
+ new_resource.stop_command("/etc/init.d/chef itoldyoutostop")
+ expect(provider).to receive(:shell_out_with_systems_locale!).with("/etc/init.d/chef itoldyoutostop")
+ provider.stop_service()
+ end
+
+ it "should call '/usr/local/etc/rc.d/service_name stop' if no stop command is specified" do
+ expect(provider).to receive(:shell_out_with_systems_locale!).with("/etc/rc.d/#{new_resource.service_name} stop")
+ provider.stop_service()
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "restart_service" do
+ it "should call 'restart' on the service_name if the resource supports it" do
+ new_resource.supports({:restart => true})
+ expect(provider).to receive(:shell_out_with_systems_locale!).with("/etc/rc.d/#{new_resource.service_name} restart")
+ provider.restart_service()
+ end
+
+ it "should call the restart_command if one has been specified" do
+ new_resource.restart_command("/etc/init.d/chef restartinafire")
+ expect(provider).to receive(:shell_out_with_systems_locale!).with("/etc/init.d/chef restartinafire")
+ provider.restart_service()
+ end
+
+ it "otherwise it should call stop and start" do
+ expect(provider).to receive(:stop_service)
+ expect(provider).to receive(:start_service)
+ provider.restart_service()
+ end
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "define_resource_requirements" do
+ before do
+ provider.current_resource = current_resource
+ end
+
+ context "when the init script is not found" do
+ before do
+ provider.init_command = nil
+ allow(provider).to receive(:builtin_service_enable_variable_name).and_return("#{new_resource.service_name}_enable")
+ end
+
+ [ "start", "reload", "restart", "enable" ].each do |action|
+ it "should raise an exception when the action is #{action}" do
+ provider.define_resource_requirements
+ provider.action = action
+ expect { provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Service)
+ end
+ end
+
+ [ "stop", "disable" ].each do |action|
+ it "should not raise an error when the action is #{action}" do
+ provider.define_resource_requirements
+ provider.action = action
+ expect { provider.process_resource_requirements }.not_to raise_error
+ end
+ end
+ end
+
+ context "when the init script is found, but the service_enable_variable_name is nil" do
+ before do
+ allow(provider).to receive(:builtin_service_enable_variable_name).and_return(nil)
+ end
+
+ [ "start", "reload", "restart", "enable" ].each do |action|
+ it "should raise an exception when the action is #{action}" do
+ provider.action = action
+ provider.define_resource_requirements
+ expect { provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Service)
+ end
+ end
+
+ [ "stop", "disable" ].each do |action|
+ it "should not raise an error when the action is #{action}" do
+ provider.action = action
+ provider.define_resource_requirements
+ expect { provider.process_resource_requirements }.not_to raise_error
+ end
+ end
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "enable_service" do
+ before do
+ provider.current_resource = current_resource
+ allow(FileUtils).to receive(:touch).with('/etc/rc.conf.local')
+ end
+ context "is builtin and disabled by default" do
+ before do
+ provider.rc_conf = "#{provider.builtin_service_enable_variable_name}=NO"
+ end
+ context "is enabled" do
+ before do
+ provider.rc_conf_local = "#{provider.builtin_service_enable_variable_name}=\"\""
+ end
+ it "should not change rc.conf.local since it is already enabled" do
+ expect(::File).not_to receive(:write)
+ provider.enable_service
+ end
+ end
+ context "is disabled" do
+ before do
+ provider.rc_conf_local = ''
+ end
+ it "should enable the service by adding a line to rc.conf.local" do
+ expect(::File).to receive(:write).with('/etc/rc.conf.local', include("#{provider.builtin_service_enable_variable_name}=\"\""))
+ expect(provider.is_enabled?).to be false
+ provider.enable_service
+ expect(provider.is_enabled?).to be true
+ end
+ end
+ end
+ context "is builtin and enabled by default" do
+ before do
+ provider.rc_conf = "#{provider.builtin_service_enable_variable_name}=\"\""
+ end
+ context "is enabled" do
+ before do
+ provider.rc_conf_local = ''
+ end
+ it "should not change rc.conf.local since it is already enabled" do
+ expect(::File).not_to receive(:write)
+ provider.enable_service
+ end
+ end
+ context "is disabled" do
+ before do
+ provider.rc_conf_local = "#{provider.builtin_service_enable_variable_name}=NO"
+ end
+ it "should enable the service by removing a line from rc.conf.local" do
+ expect(::File).to receive(:write).with('/etc/rc.conf.local', /^(?!#{provider.builtin_service_enable_variable_name})$/)
+ expect(provider.is_enabled?).to be false
+ provider.enable_service
+ expect(provider.is_enabled?).to be true
+ end
+ end
+ end
+ context "is not builtin" do
+ before do
+ provider.rc_conf = ''
+ end
+ context "is enabled" do
+ before do
+ provider.rc_conf_local = "pkg_scripts=\"#{new_resource.service_name}\"\n"
+ end
+ it "should not change rc.conf.local since it is already enabled" do
+ expect(::File).not_to receive(:write)
+ provider.enable_service
+ end
+ end
+ context "is disabled" do
+ before do
+ provider.rc_conf_local = ''
+ end
+ it "should enable the service by adding it to the pkg_scripts list" do
+ expect(::File).to receive(:write).with('/etc/rc.conf.local', "\npkg_scripts=\"#{new_resource.service_name}\"\n")
+ expect(provider.is_enabled?).to be false
+ provider.enable_service
+ expect(provider.is_enabled?).to be true
+ end
+ end
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "disable_service" do
+ before do
+ provider.current_resource = current_resource
+ allow(FileUtils).to receive(:touch).with('/etc/rc.conf.local')
+ end
+ context "is builtin and disabled by default" do
+ before do
+ provider.rc_conf = "#{provider.builtin_service_enable_variable_name}=NO"
+ end
+ context "is enabled" do
+ before do
+ provider.rc_conf_local = "#{provider.builtin_service_enable_variable_name}=\"\""
+ end
+ it "should disable the service by removing its line from rc.conf.local" do
+ expect(::File).to receive(:write).with('/etc/rc.conf.local', /^(?!#{provider.builtin_service_enable_variable_name})$/)
+ expect(provider.is_enabled?).to be true
+ provider.disable_service
+ expect(provider.is_enabled?).to be false
+ end
+ end
+ context "is disabled" do
+ before do
+ provider.rc_conf_local = ''
+ end
+ it "should not change rc.conf.local since it is already disabled" do
+ expect(::File).not_to receive(:write)
+ provider.disable_service
+ end
+ end
+ end
+ context "is builtin and enabled by default" do
+ before do
+ provider.rc_conf = "#{provider.builtin_service_enable_variable_name}=\"\""
+ end
+ context "is enabled" do
+ before do
+ provider.rc_conf_local = ''
+ end
+ it "should disable the service by adding a line to rc.conf.local" do
+ expect(::File).to receive(:write).with('/etc/rc.conf.local', include("#{provider.builtin_service_enable_variable_name}=\"NO\""))
+ expect(provider.is_enabled?).to be true
+ provider.disable_service
+ expect(provider.is_enabled?).to be false
+ end
+ end
+ context "is disabled" do
+ before do
+ provider.rc_conf_local = "#{provider.builtin_service_enable_variable_name}=NO"
+ end
+ it "should not change rc.conf.local since it is already disabled" do
+ expect(::File).not_to receive(:write)
+ provider.disable_service
+ end
+ end
+ end
+ context "is not builtin" do
+ before do
+ provider.rc_conf = ''
+ end
+ context "is enabled" do
+ before do
+ provider.rc_conf_local = "pkg_scripts=\"#{new_resource.service_name}\"\n"
+ end
+ it "should disable the service by removing it from the pkg_scripts list" do
+ expect(::File).to receive(:write).with('/etc/rc.conf.local', /^(?!#{new_resource.service_name})$/)
+ expect(provider.is_enabled?).to be true
+ provider.disable_service
+ expect(provider.is_enabled?).to be false
+ end
+ end
+ context "is disabled" do
+ before do
+ provider.rc_conf_local = ''
+ end
+ it "should not change rc.conf.local since it is already disabled" do
+ expect(::File).not_to receive(:write)
+ provider.disable_service
+ end
+ end
+ end
+ end
+
+end
diff --git a/spec/unit/provider/user_spec.rb b/spec/unit/provider/user_spec.rb
index 44434794e7..381168647b 100644
--- a/spec/unit/provider/user_spec.rb
+++ b/spec/unit/provider/user_spec.rb
@@ -91,7 +91,7 @@ describe Chef::Provider::User do
expect(@current_resource.username).to eq(@new_resource.username)
end
- it "should change the encoding of gecos to the encoding of the new resource", :ruby_gte_19_only do
+ it "should change the encoding of gecos to the encoding of the new resource" do
@pw_user.gecos.force_encoding('ASCII-8BIT')
@provider.load_current_resource
expect(@provider.current_resource.comment.encoding).to eq(@new_resource.comment.encoding)
diff --git a/spec/unit/recipe_spec.rb b/spec/unit/recipe_spec.rb
index 5ade7c86e2..8d0b1bcfd2 100644
--- a/spec/unit/recipe_spec.rb
+++ b/spec/unit/recipe_spec.rb
@@ -591,7 +591,7 @@ describe Chef::Recipe do
describe "included DSL" do
it "should include features from Chef::DSL::Audit" do
expect(recipe.singleton_class.included_modules).to include(Chef::DSL::Audit)
- expect(recipe.respond_to?(:controls)).to be true
+ expect(recipe.respond_to?(:control_group)).to be true
end
end
end
diff --git a/spec/unit/resource/chef_gem_spec.rb b/spec/unit/resource/chef_gem_spec.rb
index 657713d54f..7352a8f5fe 100644
--- a/spec/unit/resource/chef_gem_spec.rb
+++ b/spec/unit/resource/chef_gem_spec.rb
@@ -63,7 +63,12 @@ describe Chef::Resource::ChefGem, "gem_binary" do
Chef::Recipe.new("hjk", "test", run_context)
end
- let(:resource) { Chef::Resource::ChefGem.new("foo", run_context) }
+ let(:chef_gem_compile_time) { nil }
+
+ let(:resource) do
+ Chef::Config[:chef_gem_compile_time] = chef_gem_compile_time
+ Chef::Resource::ChefGem.new("foo", run_context)
+ end
before do
expect(Chef::Resource::ChefGem).to receive(:new).and_return(resource)
@@ -71,20 +76,20 @@ describe Chef::Resource::ChefGem, "gem_binary" do
it "runs the install at compile-time by default", :chef_lt_13_only do
expect(resource).to receive(:run_action).with(:install)
- expect(Chef::Log).to receive(:warn).at_least(:once)
+ expect(Chef::Log).to receive(:deprecation).at_least(:once)
recipe.chef_gem "foo"
end
# the default behavior will change in Chef-13
it "does not runs the install at compile-time by default", :chef_gte_13_only do
expect(resource).not_to receive(:run_action).with(:install)
- expect(Chef::Log).not_to receive(:warn)
+ expect(Chef::Log).not_to receive(:deprecation)
recipe.chef_gem "foo"
end
it "compile_time true installs at compile-time" do
expect(resource).to receive(:run_action).with(:install)
- expect(Chef::Log).not_to receive(:warn)
+ expect(Chef::Log).not_to receive(:deprecation)
recipe.chef_gem "foo" do
compile_time true
end
@@ -92,10 +97,65 @@ describe Chef::Resource::ChefGem, "gem_binary" do
it "compile_time false does not install at compile-time" do
expect(resource).not_to receive(:run_action).with(:install)
- expect(Chef::Log).not_to receive(:warn)
+ expect(Chef::Log).not_to receive(:deprecation)
recipe.chef_gem "foo" do
compile_time false
end
end
+
+ describe "when Chef::Config[:chef_gem_compile_time] is explicitly true" do
+ let(:chef_gem_compile_time) { true }
+
+ before do
+ expect(Chef::Log).not_to receive(:deprecation)
+ end
+
+ it "by default installs at compile-time" do
+ expect(resource).to receive(:run_action).with(:install)
+ recipe.chef_gem "foo"
+ end
+
+ it "compile_time true installs at compile-time" do
+ expect(resource).to receive(:run_action).with(:install)
+ recipe.chef_gem "foo" do
+ compile_time true
+ end
+ end
+
+ it "compile_time false does not install at compile-time" do
+ expect(resource).not_to receive(:run_action).with(:install)
+ recipe.chef_gem "foo" do
+ compile_time false
+ end
+ end
+ end
+
+ describe "when Chef::Config[:chef_gem_compile_time] is explicitly false" do
+
+ let(:chef_gem_compile_time) { false }
+
+ before do
+ expect(Chef::Log).not_to receive(:deprecation)
+ end
+
+ it "by default does not install at compile-time" do
+ expect(resource).not_to receive(:run_action).with(:install)
+ recipe.chef_gem "foo"
+ end
+
+ it "compile_time true installs at compile-time" do
+ expect(resource).to receive(:run_action).with(:install)
+ recipe.chef_gem "foo" do
+ compile_time true
+ end
+ end
+
+ it "compile_time false does not install at compile-time" do
+ expect(resource).not_to receive(:run_action).with(:install)
+ recipe.chef_gem "foo" do
+ compile_time false
+ end
+ end
+ end
end
end
diff --git a/spec/unit/resource/conditional_spec.rb b/spec/unit/resource/conditional_spec.rb
index 779c69425a..49240edfdf 100644
--- a/spec/unit/resource/conditional_spec.rb
+++ b/spec/unit/resource/conditional_spec.rb
@@ -47,7 +47,7 @@ describe Chef::Resource::Conditional do
end
describe "when created as an `only_if`" do
- describe "after running a successful command" do
+ describe "after running a successful command given as a string" do
before do
@conditional = Chef::Resource::Conditional.only_if(@parent_resource, "true")
end
@@ -57,7 +57,7 @@ describe Chef::Resource::Conditional do
end
end
- describe "after running a negative/false command" do
+ describe "after running a negative/false command given as a string" do
before do
@status.send("success?=", false)
@conditional = Chef::Resource::Conditional.only_if(@parent_resource, "false")
@@ -68,6 +68,27 @@ describe Chef::Resource::Conditional do
end
end
+ describe "after running a successful command given as an array" do
+ before do
+ @conditional = Chef::Resource::Conditional.only_if(@parent_resource, ["true"])
+ end
+
+ it "indicates that resource convergence should continue" do
+ expect(@conditional.continue?).to be true
+ end
+ end
+
+ describe "after running a negative/false command given as an array" do
+ before do
+ @status.send("success?=", false)
+ @conditional = Chef::Resource::Conditional.only_if(@parent_resource, ["false"])
+ end
+
+ it "indicates that resource convergence should not continue" do
+ expect(@conditional.continue?).to be false
+ end
+ end
+
describe 'after running a command which timed out' do
before do
@conditional = Chef::Resource::Conditional.only_if(@parent_resource, "false")
@@ -106,7 +127,7 @@ describe Chef::Resource::Conditional do
end
describe "when created as a `not_if`" do
- describe "after running a successful/true command" do
+ describe "after running a successful/true command given as a string" do
before do
@conditional = Chef::Resource::Conditional.not_if(@parent_resource, "true")
end
@@ -116,7 +137,7 @@ describe Chef::Resource::Conditional do
end
end
- describe "after running a failed/false command" do
+ describe "after running a failed/false command given as a string" do
before do
@status.send("success?=", false)
@conditional = Chef::Resource::Conditional.not_if(@parent_resource, "false")
@@ -127,6 +148,27 @@ describe Chef::Resource::Conditional do
end
end
+ describe "after running a successful/true command given as an array" do
+ before do
+ @conditional = Chef::Resource::Conditional.not_if(@parent_resource, ["true"])
+ end
+
+ it "indicates that resource convergence should not continue" do
+ expect(@conditional.continue?).to be false
+ end
+ end
+
+ describe "after running a failed/false command given as an array" do
+ before do
+ @status.send("success?=", false)
+ @conditional = Chef::Resource::Conditional.not_if(@parent_resource, ["false"])
+ end
+
+ it "indicates that resource convergence should continue" do
+ expect(@conditional.continue?).to be true
+ end
+ end
+
describe 'after running a command which timed out' do
before do
@conditional = Chef::Resource::Conditional.not_if(@parent_resource, "false")
diff --git a/spec/unit/resource/execute_spec.rb b/spec/unit/resource/execute_spec.rb
index 70b9d87d4c..09160ddbd0 100644
--- a/spec/unit/resource/execute_spec.rb
+++ b/spec/unit/resource/execute_spec.rb
@@ -28,4 +28,8 @@ describe Chef::Resource::Execute do
expect(execute_resource.guard_interpreter).to be(:execute)
end
+ it "defaults to not being a guard interpreter" do
+ expect(execute_resource.is_guard_interpreter).to eq(false)
+ end
+
end
diff --git a/spec/unit/resource/rpm_package_spec.rb b/spec/unit/resource/rpm_package_spec.rb
index d209c6a5a2..d3b505fff5 100644
--- a/spec/unit/resource/rpm_package_spec.rb
+++ b/spec/unit/resource/rpm_package_spec.rb
@@ -32,3 +32,15 @@ describe Chef::Resource::RpmPackage, "initialize" do
end
end
+
+describe Chef::Resource::RpmPackage, "allow_downgrade" do
+ before(:each) do
+ @resource = Chef::Resource::RpmPackage.new("foo")
+ end
+
+ it "should allow you to specify whether allow_downgrade is true or false" do
+ expect { @resource.allow_downgrade true }.not_to raise_error
+ expect { @resource.allow_downgrade false }.not_to raise_error
+ expect { @resource.allow_downgrade "monkey" }.to raise_error(ArgumentError)
+ end
+end
diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb
index 56c7401c92..8214021f65 100644
--- a/spec/unit/resource_spec.rb
+++ b/spec/unit/resource_spec.rb
@@ -194,12 +194,12 @@ describe Chef::Resource do
expect(@resource.name).to eql("monkey")
end
- it "should not be valid without a name" do
- expect { @resource.name false }.to raise_error(ArgumentError)
+ it "coerces arrays to names" do
+ expect(@resource.name ['a', 'b']).to eql('a, b')
end
- it "should always have a string for name" do
- expect { @resource.name Hash.new }.to raise_error(ArgumentError)
+ it "should coerce objects to a string" do
+ expect(@resource.name Object.new).to be_a(String)
end
end
@@ -258,6 +258,12 @@ describe Chef::Resource do
expected_notification = Chef::Resource::Notification.new({:service => "apache"}, :restart, @resource)
expect(@resource.delayed_notifications).to include(expected_notification)
end
+
+ it "notifies a resource with an array for its name via its prettified string name" do
+ @run_context.resource_collection << Chef::Resource::ZenMaster.new(["coffee", "tea"])
+ @resource.notifies :reload, @run_context.resource_collection.find(:zen_master => "coffee, tea")
+ expect(@resource.delayed_notifications.detect{|e| e.resource.name == "coffee, tea" && e.action == :reload}).not_to be_nil
+ end
end
describe "subscribes" do
diff --git a/spec/unit/util/diff_spec.rb b/spec/unit/util/diff_spec.rb
index ea226f1c04..b0a57a32c0 100644
--- a/spec/unit/util/diff_spec.rb
+++ b/spec/unit/util/diff_spec.rb
@@ -105,7 +105,7 @@ shared_examples_for "a diff util" do
end
end
- describe "when the default external encoding is UTF-8", :ruby_gte_19_only do
+ describe "when the default external encoding is UTF-8" do
before do
@saved_default_external = Encoding.default_external
@@ -170,7 +170,7 @@ shared_examples_for "a diff util" do
end
- describe "when the default external encoding is Latin-1", :ruby_gte_19_only do
+ describe "when the default external encoding is Latin-1" do
before do
@saved_default_external = Encoding.default_external
@@ -234,7 +234,7 @@ shared_examples_for "a diff util" do
end
end
- describe "when the default external encoding is Shift_JIS", :ruby_gte_19_only do
+ describe "when the default external encoding is Shift_JIS" do
before do
@saved_default_external = Encoding.default_external
@@ -411,7 +411,7 @@ shared_examples_for "a diff util" do
end
end
- describe "when the default external encoding is UTF-8", :ruby_gte_19_only do
+ describe "when the default external encoding is UTF-8" do
before do
@saved_default_external = Encoding.default_external
@@ -456,7 +456,7 @@ shared_examples_for "a diff util" do
end
- describe "when the default external encoding is Latin-1", :ruby_gte_19_only do
+ describe "when the default external encoding is Latin-1" do
before do
@saved_default_external = Encoding.default_external
@@ -500,7 +500,7 @@ shared_examples_for "a diff util" do
end
end
- describe "when the default external encoding is Shift-JIS", :ruby_gte_19_only do
+ describe "when the default external encoding is Shift-JIS" do
before do
@saved_default_external = Encoding.default_external
diff --git a/spec/unit/util/dsc/local_configuration_manager_spec.rb b/spec/unit/util/dsc/local_configuration_manager_spec.rb
index 1281862e67..1cff9e445b 100644
--- a/spec/unit/util/dsc/local_configuration_manager_spec.rb
+++ b/spec/unit/util/dsc/local_configuration_manager_spec.rb
@@ -65,7 +65,7 @@ EOH
let(:lcm_cmdlet_success) { true }
it 'should successfully return resource information for normally formatted output when cmdlet the cmdlet succeeds' do
- test_configuration_result = lcm.test_configuration('config')
+ test_configuration_result = lcm.test_configuration('config', {})
expect(test_configuration_result.class).to be(Array)
expect(test_configuration_result.length).to be > 0
expect(Chef::Log).not_to receive(:warn)
@@ -85,7 +85,7 @@ EOH
expect(Chef::Log).to receive(:warn).at_least(:once)
expect(lcm).to receive(:whatif_not_supported?).and_call_original
test_configuration_result = nil
- expect {test_configuration_result = lcm.test_configuration('config')}.not_to raise_error
+ expect {test_configuration_result = lcm.test_configuration('config', {})}.not_to raise_error
expect(test_configuration_result.class).to be(Array)
end
end
@@ -99,13 +99,13 @@ EOH
expect(Chef::Log).to receive(:warn).at_least(:once)
expect(lcm).to receive(:dsc_module_import_failure?).and_call_original
test_configuration_result = nil
- expect {test_configuration_result = lcm.test_configuration('config')}.not_to raise_error
+ expect {test_configuration_result = lcm.test_configuration('config', {})}.not_to raise_error
end
it 'should return a (possibly empty) array of ResourceInfo instances' do
expect(Chef::Log).to receive(:warn).at_least(:once)
test_configuration_result = nil
- expect {test_configuration_result = lcm.test_configuration('config')}.not_to raise_error
+ expect {test_configuration_result = lcm.test_configuration('config', {})}.not_to raise_error
expect(test_configuration_result.class).to be(Array)
end
end
@@ -118,7 +118,7 @@ EOH
it 'should log a warning' do
expect(Chef::Log).to receive(:warn).at_least(:once)
expect(lcm).to receive(:dsc_module_import_failure?).and_call_original
- expect {lcm.test_configuration('config')}.not_to raise_error
+ expect {lcm.test_configuration('config', {})}.not_to raise_error
end
end
end
diff --git a/spec/unit/util/path_helper_spec.rb b/spec/unit/util/path_helper_spec.rb
index 4df4b9b1ff..5756c29b90 100644
--- a/spec/unit/util/path_helper_spec.rb
+++ b/spec/unit/util/path_helper_spec.rb
@@ -189,16 +189,8 @@ describe Chef::Util::PathHelper do
end
context "not on windows", :unix_only do
- context "ruby is at least 1.9", :ruby_gte_19_only do
- it "returns a canonical path" do
- expect(PathHelper.canonical_path("/etc//apache.d/sites-enabled/../sites-available/default")).to eq("/etc/apache.d/sites-available/default")
- end
- end
-
- context "ruby is less than 1.9", :ruby_18_only do
- it "returns a canonical path" do
- expect { PathHelper.canonical_path("/etc//apache.d/sites-enabled/../sites-available/default") }.to raise_error(NotImplementedError)
- end
+ it "returns a canonical path" do
+ expect(PathHelper.canonical_path("/etc//apache.d/sites-enabled/../sites-available/default")).to eq("/etc/apache.d/sites-available/default")
end
end
end