chef 11.16.4 → 11.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +2 -2
- data/lib/chef/api_client.rb +1 -1
- data/lib/chef/chef_fs/chef_fs_data_store.rb +3 -2
- data/lib/chef/chef_fs/command_line.rb +3 -2
- data/lib/chef/chef_fs/data_handler/group_data_handler.rb +5 -1
- data/lib/chef/chef_fs/file_system/acl_entry.rb +2 -1
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +2 -1
- data/lib/chef/chef_fs/file_system/rest_list_dir.rb +3 -2
- data/lib/chef/chef_fs/file_system/rest_list_entry.rb +5 -4
- data/lib/chef/config_fetcher.rb +1 -1
- data/lib/chef/cookbook/cookbook_version_loader.rb +4 -4
- data/lib/chef/cookbook/metadata.rb +1 -1
- data/lib/chef/cookbook_version.rb +2 -2
- data/lib/chef/data_bag.rb +1 -1
- data/lib/chef/data_bag_item.rb +1 -1
- data/lib/chef/encrypted_data_bag_item/decryptor.rb +3 -3
- data/lib/chef/environment.rb +1 -1
- data/lib/chef/exceptions.rb +19 -2
- data/lib/chef/json_compat.rb +64 -45
- data/lib/chef/knife/bootstrap.rb +2 -2
- data/lib/chef/knife/bootstrap/archlinux-gems.erb +2 -2
- data/lib/chef/knife/bootstrap/centos5-gems.erb +2 -2
- data/lib/chef/knife/bootstrap/chef-aix.erb +2 -2
- data/lib/chef/knife/bootstrap/chef-full.erb +2 -2
- data/lib/chef/knife/bootstrap/fedora13-gems.erb +2 -2
- data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +2 -2
- data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +2 -2
- data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +2 -2
- data/lib/chef/knife/cookbook_site_download.rb +1 -1
- data/lib/chef/knife/cookbook_site_install.rb +34 -10
- data/lib/chef/knife/cookbook_site_list.rb +1 -1
- data/lib/chef/knife/cookbook_site_search.rb +1 -1
- data/lib/chef/knife/cookbook_site_share.rb +2 -2
- data/lib/chef/knife/cookbook_site_show.rb +3 -3
- data/lib/chef/knife/cookbook_site_unshare.rb +1 -1
- data/lib/chef/knife/core/subcommand_loader.rb +24 -0
- data/lib/chef/knife/deps.rb +3 -2
- data/lib/chef/node.rb +1 -1
- data/lib/chef/provider/deploy/revision.rb +1 -1
- data/lib/chef/provider/dsc_script.rb +32 -5
- data/lib/chef/provider/env.rb +25 -10
- data/lib/chef/provider/remote_file/cache_control_data.rb +1 -1
- data/lib/chef/resource.rb +1 -1
- data/lib/chef/resource/dsc_script.rb +2 -16
- data/lib/chef/resource_collection.rb +1 -1
- data/lib/chef/resource_reporter.rb +3 -3
- data/lib/chef/role.rb +1 -1
- data/lib/chef/run_list.rb +1 -1
- data/lib/chef/user.rb +1 -1
- data/lib/chef/util/dsc/local_configuration_manager.rb +15 -11
- data/lib/chef/util/powershell/cmdlet_result.rb +2 -2
- data/lib/chef/version.rb +1 -2
- data/spec/data/bootstrap/test-hints.erb +1 -1
- data/spec/data/bootstrap/test.erb +1 -1
- data/spec/functional/knife/cookbook_delete_spec.rb +3 -3
- data/spec/functional/knife/exec_spec.rb +1 -1
- data/spec/functional/resource/dsc_script_spec.rb +92 -47
- data/spec/functional/resource/env_spec.rb +3 -4
- data/spec/functional/util/powershell/cmdlet_spec.rb +1 -2
- data/spec/integration/knife/chef_fs_data_store_spec.rb +1 -1
- data/spec/integration/knife/chef_repo_path_spec.rb +6 -1
- data/spec/integration/knife/chef_repository_file_system_spec.rb +1 -1
- data/spec/integration/knife/chefignore_spec.rb +1 -1
- data/spec/integration/knife/common_options_spec.rb +1 -1
- data/spec/integration/knife/cookbook_api_ipv6_spec.rb +1 -1
- data/spec/integration/knife/delete_spec.rb +1 -1
- data/spec/integration/knife/deps_spec.rb +1 -1
- data/spec/integration/knife/diff_spec.rb +3 -3
- data/spec/integration/knife/download_spec.rb +3 -3
- data/spec/integration/knife/list_spec.rb +1 -1
- data/spec/integration/knife/raw_spec.rb +11 -1
- data/spec/integration/knife/redirection_spec.rb +1 -1
- data/spec/integration/knife/serve_spec.rb +1 -1
- data/spec/integration/knife/show_spec.rb +1 -1
- data/spec/integration/knife/upload_spec.rb +9 -9
- data/spec/spec_helper.rb +6 -0
- data/spec/support/shared/integration/integration_helper.rb +1 -2
- data/spec/support/shared/shared_examples.rb +10 -0
- data/spec/tiny_server.rb +2 -1
- data/spec/unit/api_client_spec.rb +3 -3
- data/spec/unit/chef_fs/data_handler/group_handler_spec.rb +63 -0
- data/spec/unit/config_fetcher_spec.rb +1 -1
- data/spec/unit/cookbook/metadata_spec.rb +7 -3
- data/spec/unit/cookbook_loader_spec.rb +1 -1
- data/spec/unit/cookbook_version_spec.rb +4 -0
- data/spec/unit/data_bag_item_spec.rb +5 -1
- data/spec/unit/data_bag_spec.rb +5 -1
- data/spec/unit/deprecation_spec.rb +1 -1
- data/spec/unit/encrypted_data_bag_item_spec.rb +14 -7
- data/spec/unit/environment_spec.rb +7 -3
- data/spec/unit/exceptions_spec.rb +6 -0
- data/spec/unit/json_compat_spec.rb +58 -17
- data/spec/unit/knife/cookbook_metadata_from_file_spec.rb +0 -1
- data/spec/unit/knife/cookbook_site_download_spec.rb +2 -1
- data/spec/unit/knife/cookbook_site_install_spec.rb +161 -116
- data/spec/unit/knife/cookbook_site_share_spec.rb +6 -6
- data/spec/unit/knife/core/bootstrap_context_spec.rb +2 -2
- data/spec/unit/knife/core/subcommand_loader_spec.rb +66 -1
- data/spec/unit/knife/data_bag_from_file_spec.rb +1 -2
- data/spec/unit/node_spec.rb +4 -0
- data/spec/unit/provider/dsc_script_spec.rb +134 -105
- data/spec/unit/provider/env/windows_spec.rb +2 -2
- data/spec/unit/provider/env_spec.rb +76 -11
- data/spec/unit/provider/remote_file/cache_control_data_spec.rb +1 -1
- data/spec/unit/resource/dsc_script_spec.rb +0 -29
- data/spec/unit/resource_collection_spec.rb +5 -1
- data/spec/unit/resource_reporter_spec.rb +3 -3
- data/spec/unit/resource_spec.rb +5 -1
- data/spec/unit/role_spec.rb +4 -0
- data/spec/unit/run_list_spec.rb +5 -1
- data/spec/unit/user_spec.rb +5 -1
- data/spec/unit/util/dsc/local_configuration_manager_spec.rb +15 -10
- metadata +11 -9
@@ -108,16 +108,16 @@ describe Chef::Knife::CookbookSiteShare do
|
|
108
108
|
File.stub(:open).and_return(true)
|
109
109
|
end
|
110
110
|
|
111
|
-
it 'should post the cookbook to "
|
112
|
-
response_text = {:uri => '
|
111
|
+
it 'should post the cookbook to "https://supermarket.getchef.com"' do
|
112
|
+
response_text = {:uri => 'https://supermarket.getchef.com/cookbooks/cookbook_name'}.to_json
|
113
113
|
@upload_response.stub(:body).and_return(response_text)
|
114
114
|
@upload_response.stub(:code).and_return(201)
|
115
|
-
Chef::CookbookSiteStreamingUploader.should_receive(:post).with(/
|
115
|
+
Chef::CookbookSiteStreamingUploader.should_receive(:post).with(/supermarket\.getchef\.com/, anything(), anything(), anything())
|
116
116
|
@knife.run
|
117
117
|
end
|
118
118
|
|
119
119
|
it 'should alert the user when a version already exists' do
|
120
|
-
response_text = {:error_messages => ['Version already exists']}
|
120
|
+
response_text = Chef::JSONCompat.to_json({:error_messages => ['Version already exists']})
|
121
121
|
@upload_response.stub(:body).and_return(response_text)
|
122
122
|
@upload_response.stub(:code).and_return(409)
|
123
123
|
lambda { @knife.run }.should raise_error(SystemExit)
|
@@ -125,7 +125,7 @@ describe Chef::Knife::CookbookSiteShare do
|
|
125
125
|
end
|
126
126
|
|
127
127
|
it 'should pass any errors on to the user' do
|
128
|
-
response_text = {:error_messages => ["You're holding it wrong"]}
|
128
|
+
response_text = Chef::JSONCompat.to_json({:error_messages => ["You're holding it wrong"]})
|
129
129
|
@upload_response.stub(:body).and_return(response_text)
|
130
130
|
@upload_response.stub(:code).and_return(403)
|
131
131
|
lambda { @knife.run }.should raise_error(SystemExit)
|
@@ -133,7 +133,7 @@ describe Chef::Knife::CookbookSiteShare do
|
|
133
133
|
end
|
134
134
|
|
135
135
|
it 'should print the body if no errors are exposed on failure' do
|
136
|
-
response_text = {:system_error => "Your call was dropped", :reason => "There's a map for that"}
|
136
|
+
response_text = Chef::JSONCompat.to_json({:system_error => "Your call was dropped", :reason => "There's a map for that"})
|
137
137
|
@upload_response.stub(:body).and_return(response_text)
|
138
138
|
@upload_response.stub(:code).and_return(500)
|
139
139
|
@knife.ui.should_receive(:error).with(/#{Regexp.escape(response_text)}/)#.ordered
|
@@ -116,13 +116,13 @@ EXPECTED
|
|
116
116
|
describe "when JSON attributes are given" do
|
117
117
|
let(:config) { {:first_boot_attributes => {:baz => :quux}} }
|
118
118
|
it "adds the attributes to first_boot" do
|
119
|
-
bootstrap_context.first_boot.
|
119
|
+
Chef::JSONCompat.to_json(bootstrap_context.first_boot).should eq(Chef::JSONCompat.to_json({:baz => :quux, :run_list => run_list}))
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
123
|
describe "when JSON attributes are NOT given" do
|
124
124
|
it "sets first_boot equal to run_list" do
|
125
|
-
bootstrap_context.first_boot.
|
125
|
+
Chef::JSONCompat.to_json(bootstrap_context.first_boot).should eq(Chef::JSONCompat.to_json({:run_list => run_list}))
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
@@ -73,7 +73,72 @@ describe Chef::Knife::SubcommandLoader do
|
|
73
73
|
@loader.site_subcommands.should include(expected_command)
|
74
74
|
end
|
75
75
|
|
76
|
-
|
76
|
+
# https://github.com/opscode/chef-dk/issues/227
|
77
|
+
#
|
78
|
+
# `knife` in ChefDK isn't from a gem install, it's directly run from a clone
|
79
|
+
# of the source, but there can be one or more versions of chef also installed
|
80
|
+
# as a gem. If the gem install contains a command that doesn't exist in the
|
81
|
+
# source tree of the "primary" chef install, it can be loaded and cause an
|
82
|
+
# error. We also want to ensure that we only load builtin commands from the
|
83
|
+
# "primary" chef install.
|
84
|
+
context "when a different version of chef is also installed as a gem" do
|
85
|
+
|
86
|
+
let(:all_found_commands) do
|
87
|
+
[
|
88
|
+
"/opt/chefdk/embedded/apps/chef/lib/chef/knife/bootstrap.rb",
|
89
|
+
"/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_bulk_delete.rb",
|
90
|
+
"/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_create.rb",
|
91
|
+
# We use the fake version 1.0.0 because that version doesn't exist,
|
92
|
+
# which ensures it won't ever equal "chef-#{Chef::VERSION}"
|
93
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/bootstrap.rb",
|
94
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/client_bulk_delete.rb",
|
95
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/client_create.rb",
|
96
|
+
# This command is "extra" compared to what's in the embedded/apps/chef install:
|
97
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/data_bag_secret_options.rb",
|
98
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-vault-2.2.4/lib/chef/knife/decrypt.rb",
|
99
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/knife-spork-1.4.1/lib/chef/knife/spork-bump.rb",
|
100
|
+
# These are fake commands that have names designed to test that the
|
101
|
+
# regex is strict enough
|
102
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-foo-#{Chef::VERSION}/lib/chef/knife/chef-foo.rb",
|
103
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/foo-chef-#{Chef::VERSION}/lib/chef/knife/foo-chef.rb",
|
104
|
+
# In a real scenario, we'd use rubygems APIs to only select the most
|
105
|
+
# recent gem, but for this test we want to check that we're doing the
|
106
|
+
# right thing both when the plugin version matches and does not match
|
107
|
+
# the current chef version. Looking at
|
108
|
+
# `SubcommandLoader::MATCHES_THIS_CHEF_GEM` and
|
109
|
+
# `SubcommandLoader::MATCHES_CHEF_GEM` should make it clear why we want
|
110
|
+
# to test these two cases.
|
111
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-bar-1.0.0/lib/chef/knife/chef-bar.rb",
|
112
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/bar-chef-1.0.0/lib/chef/knife/bar-chef.rb"
|
113
|
+
]
|
114
|
+
end
|
115
|
+
|
116
|
+
let(:expected_valid_commands) do
|
117
|
+
[
|
118
|
+
"/opt/chefdk/embedded/apps/chef/lib/chef/knife/bootstrap.rb",
|
119
|
+
"/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_bulk_delete.rb",
|
120
|
+
"/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_create.rb",
|
121
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-vault-2.2.4/lib/chef/knife/decrypt.rb",
|
122
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/knife-spork-1.4.1/lib/chef/knife/spork-bump.rb",
|
123
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-foo-#{Chef::VERSION}/lib/chef/knife/chef-foo.rb",
|
124
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/foo-chef-#{Chef::VERSION}/lib/chef/knife/foo-chef.rb",
|
125
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-bar-1.0.0/lib/chef/knife/chef-bar.rb",
|
126
|
+
"/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/bar-chef-1.0.0/lib/chef/knife/bar-chef.rb"
|
127
|
+
]
|
128
|
+
end
|
129
|
+
|
130
|
+
before do
|
131
|
+
expect(@loader).to receive(:find_files_latest_gems).with("chef/knife/*.rb").and_return(all_found_commands)
|
132
|
+
expect(@loader).to receive(:find_subcommands_via_dirglob).and_return({})
|
133
|
+
end
|
134
|
+
|
135
|
+
it "ignores commands from the non-matching gem install" do
|
136
|
+
expect(@loader.find_subcommands_via_rubygems.values).to eq(expected_valid_commands)
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "finding 3rd party plugins" do
|
77
142
|
let(:env_home) { "/home/alice" }
|
78
143
|
let(:manifest_path) { env_home + "/.chef/plugin_manifest.json" }
|
79
144
|
|
@@ -21,7 +21,6 @@ require 'spec_helper'
|
|
21
21
|
require 'chef/data_bag_item'
|
22
22
|
require 'chef/encrypted_data_bag_item'
|
23
23
|
require 'tempfile'
|
24
|
-
require 'json'
|
25
24
|
|
26
25
|
Chef::Knife::DataBagFromFile.load_deps
|
27
26
|
|
@@ -46,7 +45,7 @@ describe Chef::Knife::DataBagFromFile do
|
|
46
45
|
"greeting" => "hello",
|
47
46
|
"nested" => { "a1" => [1, 2, 3], "a2" => { "b1" => true }}
|
48
47
|
}
|
49
|
-
@db_file.write(@plain_data
|
48
|
+
@db_file.write(Chef::JSONCompat.to_json(@plain_data))
|
50
49
|
@db_file.flush
|
51
50
|
@knife.instance_variable_set(:@name_args, ['bag_name', @db_file.path])
|
52
51
|
end
|
data/spec/unit/node_spec.rb
CHANGED
@@ -762,6 +762,10 @@ describe Chef::Node do
|
|
762
762
|
end
|
763
763
|
serialized_node.run_list.should == node.run_list
|
764
764
|
end
|
765
|
+
|
766
|
+
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
|
767
|
+
let(:subject) { node.from_file(File.expand_path("nodes/test.example.com.rb", CHEF_SPEC_DATA)) }
|
768
|
+
end
|
765
769
|
end
|
766
770
|
|
767
771
|
describe "to_s" do
|
@@ -22,123 +22,152 @@ require 'chef/util/dsc/resource_info'
|
|
22
22
|
require 'spec_helper'
|
23
23
|
|
24
24
|
describe Chef::Provider::DscScript do
|
25
|
-
|
26
|
-
node
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
describe '#load_current_resource' do
|
38
|
-
it "describes the resource as converged if there were 0 DSC resources" do
|
39
|
-
allow(provider).to receive(:run_configuration).with(:test).and_return([])
|
40
|
-
provider.load_current_resource
|
41
|
-
provider.instance_variable_get('@resource_converged').should be_true
|
25
|
+
context 'when DSC is available' do
|
26
|
+
let (:node) {
|
27
|
+
node = Chef::Node.new
|
28
|
+
node.automatic[:languages][:powershell][:version] = '4.0'
|
29
|
+
node
|
30
|
+
}
|
31
|
+
let (:events) { Chef::EventDispatch::Dispatcher.new }
|
32
|
+
let (:run_context) { Chef::RunContext.new(node, {}, events) }
|
33
|
+
let (:resource) { Chef::Resource::DscScript.new("script", run_context) }
|
34
|
+
let (:provider) do
|
35
|
+
Chef::Provider::DscScript.new(resource, run_context)
|
42
36
|
end
|
43
37
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
38
|
+
describe '#load_current_resource' do
|
39
|
+
it "describes the resource as converged if there were 0 DSC resources" do
|
40
|
+
allow(provider).to receive(:run_configuration).with(:test).and_return([])
|
41
|
+
provider.load_current_resource
|
42
|
+
provider.instance_variable_get('@resource_converged').should be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
it "describes the resource as not converged if there is 1 DSC resources that is converged" do
|
46
|
+
dsc_resource_info = Chef::Util::DSC::ResourceInfo.new('resource', false, ['nothing will change something'])
|
47
|
+
allow(provider).to receive(:run_configuration).with(:test).and_return([dsc_resource_info])
|
48
|
+
provider.load_current_resource
|
49
|
+
provider.instance_variable_get('@resource_converged').should be_true
|
50
|
+
end
|
51
|
+
|
52
|
+
it "describes the resource as not converged if there is 1 DSC resources that is not converged" do
|
53
|
+
dsc_resource_info = Chef::Util::DSC::ResourceInfo.new('resource', true, ['will change something'])
|
54
|
+
allow(provider).to receive(:run_configuration).with(:test).and_return([dsc_resource_info])
|
55
|
+
provider.load_current_resource
|
56
|
+
provider.instance_variable_get('@resource_converged').should be_false
|
57
|
+
end
|
58
|
+
|
59
|
+
it "describes the resource as not converged if there are any DSC resources that are not converged" do
|
60
|
+
dsc_resource_info1 = Chef::Util::DSC::ResourceInfo.new('resource', true, ['will change something'])
|
61
|
+
dsc_resource_info2 = Chef::Util::DSC::ResourceInfo.new('resource', false, ['nothing will change something'])
|
62
|
+
|
63
|
+
allow(provider).to receive(:run_configuration).with(:test).and_return([dsc_resource_info1, dsc_resource_info2])
|
64
|
+
provider.load_current_resource
|
65
|
+
provider.instance_variable_get('@resource_converged').should be_false
|
66
|
+
end
|
67
|
+
|
68
|
+
it "describes the resource as converged if all DSC resources that are converged" do
|
69
|
+
dsc_resource_info1 = Chef::Util::DSC::ResourceInfo.new('resource', false, ['nothing will change something'])
|
70
|
+
dsc_resource_info2 = Chef::Util::DSC::ResourceInfo.new('resource', false, ['nothing will change something'])
|
71
|
+
|
72
|
+
allow(provider).to receive(:run_configuration).with(:test).and_return([dsc_resource_info1, dsc_resource_info2])
|
73
|
+
provider.load_current_resource
|
74
|
+
provider.instance_variable_get('@resource_converged').should be_true
|
75
|
+
end
|
49
76
|
end
|
50
77
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
78
|
+
describe '#generate_configuration_document' do
|
79
|
+
# I think integration tests should cover these cases
|
80
|
+
|
81
|
+
it 'uses configuration_document_from_script_path when a dsc script file is given' do
|
82
|
+
allow(provider).to receive(:load_current_resource)
|
83
|
+
resource.command("path_to_script")
|
84
|
+
generator = double('Chef::Util::DSC::ConfigurationGenerator')
|
85
|
+
generator.should_receive(:configuration_document_from_script_path)
|
86
|
+
allow(Chef::Util::DSC::ConfigurationGenerator).to receive(:new).and_return(generator)
|
87
|
+
provider.send(:generate_configuration_document, 'tmp', nil)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'uses configuration_document_from_script_code when a the dsc resource is given' do
|
91
|
+
allow(provider).to receive(:load_current_resource)
|
92
|
+
resource.code("ImADSCResource{}")
|
93
|
+
generator = double('Chef::Util::DSC::ConfigurationGenerator')
|
94
|
+
generator.should_receive(:configuration_document_from_script_code)
|
95
|
+
allow(Chef::Util::DSC::ConfigurationGenerator).to receive(:new).and_return(generator)
|
96
|
+
provider.send(:generate_configuration_document, 'tmp', nil)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should noop if neither code or command are provided' do
|
100
|
+
allow(provider).to receive(:load_current_resource)
|
101
|
+
generator = double('Chef::Util::DSC::ConfigurationGenerator')
|
102
|
+
generator.should_receive(:configuration_document_from_script_code).with('', anything(), anything())
|
103
|
+
allow(Chef::Util::DSC::ConfigurationGenerator).to receive(:new).and_return(generator)
|
104
|
+
provider.send(:generate_configuration_document, 'tmp', nil)
|
105
|
+
end
|
56
106
|
end
|
57
107
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
108
|
+
describe 'action_run' do
|
109
|
+
it 'should converge the script if it is not converged' do
|
110
|
+
dsc_resource_info = Chef::Util::DSC::ResourceInfo.new('resource', true, ['will change something'])
|
111
|
+
allow(provider).to receive(:run_configuration).with(:test).and_return([dsc_resource_info])
|
112
|
+
allow(provider).to receive(:run_configuration).with(:set)
|
113
|
+
|
114
|
+
provider.run_action(:run)
|
115
|
+
resource.should be_updated
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should not converge if the script is already converged' do
|
119
|
+
allow(provider).to receive(:run_configuration).with(:test).and_return([])
|
120
|
+
|
121
|
+
provider.run_action(:run)
|
122
|
+
resource.should_not be_updated
|
123
|
+
end
|
65
124
|
end
|
66
125
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
126
|
+
describe '#generate_description' do
|
127
|
+
it 'removes the resource name from the beginning of any log line from the LCM' do
|
128
|
+
dsc_resource_info = Chef::Util::DSC::ResourceInfo.new('resourcename', true, ['resourcename doing something', 'lastline'])
|
129
|
+
provider.instance_variable_set('@dsc_resources_info', [dsc_resource_info])
|
130
|
+
provider.send(:generate_description)[1].should match(/converge DSC resource resourcename by doing something/)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'ignores the last line' do
|
134
|
+
dsc_resource_info = Chef::Util::DSC::ResourceInfo.new('resourcename', true, ['resourcename doing something', 'lastline'])
|
135
|
+
provider.instance_variable_set('@dsc_resources_info', [dsc_resource_info])
|
136
|
+
provider.send(:generate_description)[1].should_not match(/lastline/)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'reports a dsc resource has not been changed if the LCM reported no change was required' do
|
140
|
+
dsc_resource_info = Chef::Util::DSC::ResourceInfo.new('resourcename', false, ['resourcename does nothing', 'lastline'])
|
141
|
+
provider.instance_variable_set('@dsc_resources_info', [dsc_resource_info])
|
142
|
+
provider.send(:generate_description)[1].should match(/converge DSC resource resourcename by doing nothing/)
|
143
|
+
end
|
74
144
|
end
|
75
145
|
end
|
76
146
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
generator = double('Chef::Util::DSC::ConfigurationGenerator')
|
101
|
-
generator.should_receive(:configuration_document_from_script_code).with('', anything(), anything())
|
102
|
-
allow(Chef::Util::DSC::ConfigurationGenerator).to receive(:new).and_return(generator)
|
103
|
-
provider.send(:generate_configuration_document, 'tmp', nil)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
describe 'action_run' do
|
108
|
-
it 'should converge the script if it is not converged' do
|
109
|
-
dsc_resource_info = Chef::Util::DSC::ResourceInfo.new('resource', true, ['will change something'])
|
110
|
-
allow(provider).to receive(:run_configuration).with(:test).and_return([dsc_resource_info])
|
111
|
-
allow(provider).to receive(:run_configuration).with(:set)
|
112
|
-
|
113
|
-
provider.run_action(:run)
|
114
|
-
resource.should be_updated
|
115
|
-
end
|
116
|
-
|
117
|
-
it 'should not converge if the script is already converged' do
|
118
|
-
allow(provider).to receive(:run_configuration).with(:test).and_return([])
|
119
|
-
|
120
|
-
provider.run_action(:run)
|
121
|
-
resource.should_not be_updated
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
describe '#generate_description' do
|
126
|
-
it 'removes the resource name from the beginning of any log line from the LCM' do
|
127
|
-
dsc_resource_info = Chef::Util::DSC::ResourceInfo.new('resourcename', true, ['resourcename doing something', 'lastline'])
|
128
|
-
provider.instance_variable_set('@dsc_resources_info', [dsc_resource_info])
|
129
|
-
provider.send(:generate_description)[1].should match(/converge DSC resource resourcename by doing something/)
|
130
|
-
end
|
131
|
-
|
132
|
-
it 'ignores the last line' do
|
133
|
-
dsc_resource_info = Chef::Util::DSC::ResourceInfo.new('resourcename', true, ['resourcename doing something', 'lastline'])
|
134
|
-
provider.instance_variable_set('@dsc_resources_info', [dsc_resource_info])
|
135
|
-
provider.send(:generate_description)[1].should_not match(/lastline/)
|
136
|
-
end
|
147
|
+
context 'when Dsc is not available' do
|
148
|
+
let (:node) { Chef::Node.new }
|
149
|
+
let (:events) { Chef::EventDispatch::Dispatcher.new }
|
150
|
+
let (:run_context) { Chef::RunContext.new(node, {}, events) }
|
151
|
+
let (:resource) { Chef::Resource::DscScript.new('script', run_context) }
|
152
|
+
let (:provider) { Chef::Provider::DscScript.new(resource, run_context) }
|
153
|
+
|
154
|
+
describe 'action_run' do
|
155
|
+
['1.0', '2.0', '3.0'].each do |version|
|
156
|
+
it "raises an exception for powershell version '#{version}'" do
|
157
|
+
node.automatic[:languages][:powershell][:version] = version
|
158
|
+
|
159
|
+
expect {
|
160
|
+
provider.run_action(:run)
|
161
|
+
}.to raise_error(Chef::Exceptions::NoProviderAvailable)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'raises an exception if Powershell is not present' do
|
166
|
+
expect {
|
167
|
+
provider.run_action(:run)
|
168
|
+
}.to raise_error(Chef::Exceptions::NoProviderAvailable)
|
169
|
+
end
|
137
170
|
|
138
|
-
it 'reports a dsc resource has not been changed if the LCM reported no change was required' do
|
139
|
-
dsc_resource_info = Chef::Util::DSC::ResourceInfo.new('resourcename', false, ['resourcename does nothing', 'lastline'])
|
140
|
-
provider.instance_variable_set('@dsc_resources_info', [dsc_resource_info])
|
141
|
-
provider.send(:generate_description)[1].should match(/converge DSC resource resourcename by doing nothing/)
|
142
171
|
end
|
143
172
|
end
|
144
173
|
end
|
@@ -53,7 +53,7 @@ describe Chef::Provider::Env::Windows, :windows_only do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
it "should update the ruby ENV object when it updates the value" do
|
56
|
-
provider.should_receive(:
|
56
|
+
provider.should_receive(:requires_modify_or_create?).and_return(true)
|
57
57
|
new_resource.value("foobar")
|
58
58
|
provider.action_modify
|
59
59
|
expect(ENV['CHEF_WINDOWS_ENV_TEST']).to eql('foobar')
|
@@ -92,7 +92,7 @@ describe Chef::Provider::Env::Windows, :windows_only do
|
|
92
92
|
end
|
93
93
|
|
94
94
|
it "replaces Windows system variables" do
|
95
|
-
provider.should_receive(:
|
95
|
+
provider.should_receive(:requires_modify_or_create?).and_return(true)
|
96
96
|
provider.should_receive(:expand_path).with(system_root).and_return(system_root_value)
|
97
97
|
provider.action_modify
|
98
98
|
expect(ENV['PATH']).to eql(system_root_value)
|
@@ -88,20 +88,20 @@ describe Chef::Provider::Env do
|
|
88
88
|
|
89
89
|
it "should check to see if the values are the same if the key exists" do
|
90
90
|
@provider.key_exists = true
|
91
|
-
@provider.should_receive(:
|
91
|
+
@provider.should_receive(:requires_modify_or_create?).and_return(false)
|
92
92
|
@provider.action_create
|
93
93
|
end
|
94
94
|
|
95
95
|
it "should call modify_env if the key exists and values are not equal" do
|
96
96
|
@provider.key_exists = true
|
97
|
-
@provider.stub(:
|
97
|
+
@provider.stub(:requires_modify_or_create?).and_return(true)
|
98
98
|
@provider.should_receive(:modify_env).and_return(true)
|
99
99
|
@provider.action_create
|
100
100
|
end
|
101
101
|
|
102
102
|
it "should set the new_resources updated flag when it updates an existing value" do
|
103
103
|
@provider.key_exists = true
|
104
|
-
@provider.stub(:
|
104
|
+
@provider.stub(:requires_modify_or_create?).and_return(true)
|
105
105
|
@provider.stub(:modify_env).and_return(true)
|
106
106
|
@provider.action_create
|
107
107
|
@new_resource.should be_updated
|
@@ -147,20 +147,20 @@ describe Chef::Provider::Env do
|
|
147
147
|
end
|
148
148
|
|
149
149
|
it "should call modify_group if the key exists and values are not equal" do
|
150
|
-
@provider.should_receive(:
|
150
|
+
@provider.should_receive(:requires_modify_or_create?).and_return(true)
|
151
151
|
@provider.should_receive(:modify_env).and_return(true)
|
152
152
|
@provider.action_modify
|
153
153
|
end
|
154
154
|
|
155
155
|
it "should set the new resources updated flag to true if modify_env is called" do
|
156
|
-
@provider.stub(:
|
156
|
+
@provider.stub(:requires_modify_or_create?).and_return(true)
|
157
157
|
@provider.stub(:modify_env).and_return(true)
|
158
158
|
@provider.action_modify
|
159
159
|
@new_resource.should be_updated
|
160
160
|
end
|
161
161
|
|
162
162
|
it "should not call modify_env if the key exists but the values are equal" do
|
163
|
-
@provider.should_receive(:
|
163
|
+
@provider.should_receive(:requires_modify_or_create?).and_return(false)
|
164
164
|
@provider.should_not_receive(:modify_env)
|
165
165
|
@provider.action_modify
|
166
166
|
end
|
@@ -198,9 +198,31 @@ describe Chef::Provider::Env do
|
|
198
198
|
@provider.delete_element.should eql(true)
|
199
199
|
@new_resource.should be_updated
|
200
200
|
end
|
201
|
+
|
202
|
+
context "when new_resource's value contains the delimiter" do
|
203
|
+
it "should return false if all the elements are deleted" do
|
204
|
+
# This indicates that the entire key needs to be deleted
|
205
|
+
@new_resource.value("C:/foo/bin;C:/bar/bin")
|
206
|
+
@provider.delete_element.should eql(false)
|
207
|
+
@new_resource.should_not be_updated # This will be updated in action_delete
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should return true if any, but not all, of the elements are deleted" do
|
211
|
+
@new_resource.value("C:/foo/bin;C:/notbaz/bin")
|
212
|
+
@provider.should_receive(:create_env)
|
213
|
+
@provider.delete_element.should eql(true)
|
214
|
+
@new_resource.should be_updated
|
215
|
+
end
|
216
|
+
|
217
|
+
it "should return true if none of the elements are deleted" do
|
218
|
+
@new_resource.value("C:/notfoo/bin;C:/notbaz/bin")
|
219
|
+
@provider.delete_element.should eql(true)
|
220
|
+
@new_resource.should_not be_updated
|
221
|
+
end
|
222
|
+
end
|
201
223
|
end
|
202
224
|
|
203
|
-
describe "
|
225
|
+
describe "requires_modify_or_create?" do
|
204
226
|
before(:each) do
|
205
227
|
@new_resource.value("C:/bar")
|
206
228
|
@current_resource = @new_resource.clone
|
@@ -208,25 +230,68 @@ describe Chef::Provider::Env do
|
|
208
230
|
end
|
209
231
|
|
210
232
|
it "should return false if the values are equal" do
|
211
|
-
@provider.
|
233
|
+
@provider.requires_modify_or_create?.should be_false
|
212
234
|
end
|
213
235
|
|
214
236
|
it "should return true if the values not are equal" do
|
215
237
|
@new_resource.value("C:/elsewhere")
|
216
|
-
@provider.
|
238
|
+
@provider.requires_modify_or_create?.should be_true
|
217
239
|
end
|
218
240
|
|
219
241
|
it "should return false if the current value contains the element" do
|
220
242
|
@new_resource.delim(";")
|
221
243
|
@current_resource.value("C:/bar;C:/foo;C:/baz")
|
222
244
|
|
223
|
-
@provider.
|
245
|
+
@provider.requires_modify_or_create?.should be_false
|
224
246
|
end
|
225
247
|
|
226
248
|
it "should return true if the current value does not contain the element" do
|
227
249
|
@new_resource.delim(";")
|
228
250
|
@current_resource.value("C:/biz;C:/foo/bin;C:/baz")
|
229
|
-
@provider.
|
251
|
+
@provider.requires_modify_or_create?.should be_true
|
252
|
+
end
|
253
|
+
|
254
|
+
context "when new_resource's value contains the delimiter" do
|
255
|
+
it "should return false if all the current values are contained" do
|
256
|
+
@new_resource.value("C:/biz;C:/baz")
|
257
|
+
@new_resource.delim(";")
|
258
|
+
@current_resource.value("C:/biz;C:/foo/bin;C:/baz")
|
259
|
+
@provider.requires_modify_or_create?.should be_false
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should return true if any of the new values are not contained" do
|
263
|
+
@new_resource.value("C:/biz;C:/baz;C:/bin")
|
264
|
+
@new_resource.delim(";")
|
265
|
+
@current_resource.value("C:/biz;C:/foo/bin;C:/baz")
|
266
|
+
@provider.requires_modify_or_create?.should be_true
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
describe "modify_env" do
|
272
|
+
before(:each) do
|
273
|
+
@provider.stub(:create_env).and_return(true)
|
274
|
+
@new_resource.delim ";"
|
275
|
+
|
276
|
+
@current_resource = Chef::Resource::Env.new("FOO")
|
277
|
+
@current_resource.value "C:/foo/bin"
|
278
|
+
@provider.current_resource = @current_resource
|
279
|
+
end
|
280
|
+
|
281
|
+
it "should not modify the variable passed to the resource" do
|
282
|
+
new_value = "C:/bar/bin"
|
283
|
+
passed_value = new_value.dup
|
284
|
+
@new_resource.value(passed_value)
|
285
|
+
@provider.modify_env
|
286
|
+
passed_value.should == new_value
|
287
|
+
end
|
288
|
+
|
289
|
+
it "should only add values not already contained when a delimiter is provided" do
|
290
|
+
@new_resource.value("C:/foo;C:/bar;C:/baz")
|
291
|
+
@new_resource.delim(";")
|
292
|
+
@current_resource.value("C:/foo/bar;C:/bar;C:/baz")
|
293
|
+
@provider.modify_env
|
294
|
+
@new_resource.value.should eq("C:/foo;C:/foo/bar;C:/bar;C:/baz")
|
230
295
|
end
|
231
296
|
end
|
232
297
|
end
|