chef 11.12.0.alpha.1-x86-mingw32 → 11.12.0.rc.1-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/chef/api_client/registration.rb +46 -9
- data/lib/chef/application.rb +1 -0
- data/lib/chef/application/client.rb +25 -24
- data/lib/chef/client.rb +34 -0
- data/lib/chef/config.rb +11 -0
- data/lib/chef/cookbook/chefignore.rb +10 -2
- data/lib/chef/cookbook/metadata.rb +31 -3
- data/lib/chef/cookbook/synchronizer.rb +2 -2
- data/lib/chef/cookbook/syntax_check.rb +4 -4
- data/lib/chef/encrypted_data_bag_item.rb +37 -1
- data/lib/chef/exceptions.rb +1 -0
- data/lib/chef/guard_interpreter/default_guard_interpreter.rb +42 -0
- data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +122 -0
- data/lib/chef/http.rb +0 -1
- data/lib/chef/http/decompressor.rb +7 -4
- data/lib/chef/http/simple.rb +5 -0
- data/lib/chef/http/validate_content_length.rb +28 -12
- data/lib/chef/knife.rb +1 -0
- data/lib/chef/knife/client_bulk_delete.rb +48 -9
- data/lib/chef/knife/client_delete.rb +4 -4
- data/lib/chef/knife/cookbook_bulk_delete.rb +1 -1
- data/lib/chef/knife/cookbook_upload.rb +17 -7
- data/lib/chef/knife/core/bootstrap_context.rb +1 -1
- data/lib/chef/knife/core/ui.rb +42 -5
- data/lib/chef/knife/node_run_list_add.rb +31 -2
- data/lib/chef/knife/ssh.rb +44 -31
- data/lib/chef/knife/ssl_check.rb +213 -0
- data/lib/chef/knife/ssl_fetch.rb +145 -0
- data/lib/chef/mixin/deep_merge.rb +13 -5
- data/lib/chef/mixin/shell_out.rb +9 -3
- data/lib/chef/node.rb +23 -4
- data/lib/chef/node/immutable_collections.rb +32 -0
- data/lib/chef/platform/provider_mapping.rb +21 -18
- data/lib/chef/platform/query_helpers.rb +10 -2
- data/lib/chef/policy_builder/expand_node_object.rb +3 -6
- data/lib/chef/provider/cron.rb +25 -3
- data/lib/chef/provider/mount/mount.rb +1 -1
- data/lib/chef/provider/package/dpkg.rb +2 -1
- data/lib/chef/provider/package/windows.rb +80 -0
- data/lib/chef/provider/package/windows/msi.rb +69 -0
- data/lib/chef/provider/powershell_script.rb +19 -6
- data/lib/chef/provider/service/solaris.rb +11 -7
- data/lib/chef/resource.rb +18 -5
- data/lib/chef/resource/conditional.rb +20 -7
- data/lib/chef/resource/cron.rb +18 -2
- data/lib/chef/resource/execute.rb +0 -2
- data/lib/chef/resource/powershell_script.rb +23 -1
- data/lib/chef/resource/script.rb +25 -0
- data/lib/chef/resource/subversion.rb +4 -0
- data/lib/chef/resource/windows_package.rb +79 -0
- data/lib/chef/resource/windows_script.rb +0 -5
- data/lib/chef/resources.rb +1 -0
- data/lib/chef/rest.rb +6 -1
- data/lib/chef/run_context.rb +22 -2
- data/lib/chef/run_context/cookbook_compiler.rb +12 -0
- data/lib/chef/util/editor.rb +92 -0
- data/lib/chef/util/file_edit.rb +22 -54
- data/lib/chef/version.rb +2 -2
- data/lib/chef/win32/api/installer.rb +166 -0
- data/lib/chef/win32/version.rb +8 -0
- data/spec/data/standalone_cookbook/Gemfile +1 -0
- data/spec/data/standalone_cookbook/chefignore +9 -0
- data/spec/data/standalone_cookbook/recipes/default.rb +3 -0
- data/spec/data/standalone_cookbook/vendor/bundle/ruby/2.0.0/gems/multi_json-1.9.0/lib/multi_json.rb +1 -0
- data/spec/functional/resource/powershell_spec.rb +262 -1
- data/spec/functional/win32/versions_spec.rb +3 -3
- data/spec/integration/knife/chefignore_spec.rb +1 -2
- data/spec/integration/knife/raw_spec.rb +8 -13
- data/spec/integration/knife/redirection_spec.rb +6 -14
- data/spec/integration/solo/solo_spec.rb +19 -0
- data/spec/support/shared/functional/windows_script.rb +1 -1
- data/spec/support/shared/integration/app_server_support.rb +42 -0
- data/spec/support/shared/integration/integration_helper.rb +1 -0
- data/spec/support/shared/unit/script_resource.rb +38 -0
- data/spec/unit/api_client/registration_spec.rb +109 -38
- data/spec/unit/application/client_spec.rb +48 -1
- data/spec/unit/cookbook/chefignore_spec.rb +10 -0
- data/spec/unit/cookbook/metadata_spec.rb +45 -1
- data/spec/unit/cookbook/syntax_check_spec.rb +28 -0
- data/spec/unit/cookbook_spec.rb +0 -10
- data/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb +56 -0
- data/spec/unit/http/simple_spec.rb +32 -0
- data/spec/unit/http/validate_content_length_spec.rb +187 -0
- data/spec/unit/knife/bootstrap_spec.rb +13 -4
- data/spec/unit/knife/client_bulk_delete_spec.rb +123 -38
- data/spec/unit/knife/client_delete_spec.rb +4 -4
- data/spec/unit/knife/cookbook_upload_spec.rb +181 -88
- data/spec/unit/knife/core/bootstrap_context_spec.rb +11 -1
- data/spec/unit/knife/core/ui_spec.rb +109 -38
- data/spec/unit/knife/node_run_list_add_spec.rb +24 -1
- data/spec/unit/knife/ssh_spec.rb +17 -6
- data/spec/unit/knife/ssl_check_spec.rb +187 -0
- data/spec/unit/knife/ssl_fetch_spec.rb +151 -0
- data/spec/unit/mixin/deep_merge_spec.rb +17 -0
- data/spec/unit/node/immutable_collections_spec.rb +55 -0
- data/spec/unit/node_spec.rb +9 -0
- data/spec/unit/platform/query_helpers_spec.rb +32 -0
- data/spec/unit/platform_spec.rb +193 -175
- data/spec/unit/policy_builder/expand_node_object_spec.rb +1 -1
- data/spec/unit/provider/cron_spec.rb +175 -1
- data/spec/unit/provider/mount/mount_spec.rb +33 -3
- data/spec/unit/provider/package/dpkg_spec.rb +4 -0
- data/spec/unit/provider/package/windows/msi_spec.rb +60 -0
- data/spec/unit/provider/package/windows_spec.rb +80 -0
- data/spec/unit/provider/service/macosx_spec.rb +3 -3
- data/spec/unit/provider/service/solaris_smf_service_spec.rb +35 -10
- data/spec/unit/pure_application_spec.rb +32 -0
- data/spec/unit/recipe_spec.rb +4 -0
- data/spec/unit/resource/conditional_spec.rb +13 -12
- data/spec/unit/resource/cron_spec.rb +7 -2
- data/spec/unit/resource/powershell_spec.rb +85 -2
- data/spec/unit/resource/subversion_spec.rb +5 -0
- data/spec/unit/resource/windows_package_spec.rb +74 -0
- data/spec/unit/resource_spec.rb +23 -1
- data/spec/unit/rest_spec.rb +15 -0
- data/spec/unit/run_context/cookbook_compiler_spec.rb +12 -0
- data/spec/unit/run_context_spec.rb +7 -0
- data/spec/unit/util/editor_spec.rb +152 -0
- data/spec/unit/util/file_edit_spec.rb +37 -1
- metadata +41 -30
@@ -124,12 +124,21 @@ describe Chef::Knife::Bootstrap do
|
|
124
124
|
end
|
125
125
|
|
126
126
|
describe "specifying no_proxy with various entries" do
|
127
|
-
subject(:knife)
|
128
|
-
|
127
|
+
subject(:knife) do
|
128
|
+
k = described_class.new
|
129
|
+
k.instance_variable_set("@template_file", template_file)
|
130
|
+
k.parse_options(options)
|
131
|
+
k.merge_configs
|
132
|
+
k
|
133
|
+
end
|
134
|
+
|
135
|
+
# Include a data bag secret in the options to prevent Bootstrap from
|
136
|
+
# attempting to access /etc/chef/encrypted_data_bag_secret, which
|
137
|
+
# can fail when the file exists but can't be accessed by the user
|
138
|
+
# running the tests.
|
139
|
+
let(:options){ ["--bootstrap-no-proxy", setting, "-s", "foo"] }
|
129
140
|
let(:template_file) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "no_proxy.erb")) }
|
130
141
|
let(:rendered_template) do
|
131
|
-
knife.instance_variable_set("@template_file", template_file)
|
132
|
-
knife.parse_options(options)
|
133
142
|
template_string = knife.read_template
|
134
143
|
knife.render_template(template_string)
|
135
144
|
end
|
@@ -19,60 +19,145 @@
|
|
19
19
|
require 'spec_helper'
|
20
20
|
|
21
21
|
describe Chef::Knife::ClientBulkDelete do
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
22
|
+
let(:stdout_io) { StringIO.new }
|
23
|
+
let(:stdout) {stdout_io.string}
|
24
|
+
|
25
|
+
let(:knife) {
|
26
|
+
k = Chef::Knife::ClientBulkDelete.new
|
27
|
+
k.name_args = name_args
|
28
|
+
k.config = option_args
|
29
|
+
k.ui.stub(:stdout).and_return(stdout_io)
|
30
|
+
k.ui.stub(:confirm).and_return(knife_confirm)
|
31
|
+
k.ui.stub(:confirm_without_exit).and_return(knife_confirm)
|
32
|
+
k
|
33
|
+
}
|
34
|
+
|
35
|
+
let(:name_args) { [ "." ] }
|
36
|
+
let(:option_args) { {} }
|
37
|
+
|
38
|
+
let(:knife_confirm) { true }
|
39
|
+
|
40
|
+
let(:nonvalidator_client_names) { %w{tim dan stephen} }
|
41
|
+
let(:nonvalidator_clients) {
|
42
|
+
clients = Hash.new
|
43
|
+
|
44
|
+
nonvalidator_client_names.each do |client_name|
|
33
45
|
client = Chef::ApiClient.new()
|
34
46
|
client.name(client_name)
|
35
47
|
client.stub(:destroy).and_return(true)
|
36
|
-
|
48
|
+
clients[client_name] = client
|
49
|
+
end
|
50
|
+
|
51
|
+
clients
|
52
|
+
}
|
53
|
+
|
54
|
+
let(:validator_client_names) { %w{myorg-validator} }
|
55
|
+
let(:validator_clients) {
|
56
|
+
clients = Hash.new
|
57
|
+
|
58
|
+
validator_client_names.each do |validator_client_name|
|
59
|
+
validator_client = Chef::ApiClient.new()
|
60
|
+
validator_client.name(validator_client_name)
|
61
|
+
validator_client.stub(:validator).and_return(true)
|
62
|
+
validator_client.stub(:destroy).and_return(true)
|
63
|
+
clients[validator_client_name] = validator_client
|
37
64
|
end
|
38
|
-
|
65
|
+
|
66
|
+
clients
|
67
|
+
}
|
68
|
+
|
69
|
+
let(:client_names) { nonvalidator_client_names + validator_client_names}
|
70
|
+
let(:clients) {
|
71
|
+
nonvalidator_clients.merge(validator_clients)
|
72
|
+
}
|
73
|
+
|
74
|
+
before(:each) do
|
75
|
+
Chef::ApiClient.stub(:list).and_return(clients)
|
39
76
|
end
|
40
77
|
|
41
78
|
describe "run" do
|
79
|
+
describe "without a regex" do
|
80
|
+
let(:name_args) { [ ] }
|
42
81
|
|
43
|
-
|
44
|
-
|
45
|
-
|
82
|
+
it "should exit if the regex is not provided" do
|
83
|
+
lambda { knife.run }.should raise_error(SystemExit)
|
84
|
+
end
|
46
85
|
end
|
47
86
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
87
|
+
describe "with any clients" do
|
88
|
+
it "should get the list of the clients" do
|
89
|
+
Chef::ApiClient.should_receive(:list)
|
90
|
+
knife.run
|
91
|
+
end
|
52
92
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
93
|
+
it "should print the name of the clients" do
|
94
|
+
knife.run
|
95
|
+
client_names.each do |client_name|
|
96
|
+
stdout.should include(client_name)
|
97
|
+
end
|
98
|
+
end
|
57
99
|
|
58
|
-
|
59
|
-
|
60
|
-
|
100
|
+
it "should confirm you really want to delete them" do
|
101
|
+
knife.ui.should_receive(:confirm)
|
102
|
+
knife.run
|
61
103
|
end
|
62
|
-
@knife.run
|
63
|
-
end
|
64
104
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
105
|
+
describe "without --delete-validators" do
|
106
|
+
it "should mention that validator clients wont be deleted" do
|
107
|
+
knife.run
|
108
|
+
stdout.should include("Following clients are validators and will not be deleted.")
|
109
|
+
info = stdout.index "Following clients are validators and will not be deleted."
|
110
|
+
val = stdout.index "myorg-validator"
|
111
|
+
(val > info).should be_true
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should only delete nonvalidator clients" do
|
115
|
+
nonvalidator_clients.each_value do |c|
|
116
|
+
c.should_receive(:destroy)
|
117
|
+
end
|
118
|
+
|
119
|
+
validator_clients.each_value do |c|
|
120
|
+
c.should_not_receive(:destroy)
|
121
|
+
end
|
122
|
+
|
123
|
+
knife.run
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "with --delete-validators" do
|
128
|
+
let(:option_args) { {:delete_validators => true} }
|
129
|
+
|
130
|
+
it "should mention that validator clients will be deleted" do
|
131
|
+
knife.run
|
132
|
+
stdout.should include("The following validators will be deleted")
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should confirm twice" do
|
136
|
+
knife.ui.should_receive(:confirm).once
|
137
|
+
knife.ui.should_receive(:confirm_without_exit).once
|
138
|
+
knife.run
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should delete all clients" do
|
142
|
+
clients.each_value do |c|
|
143
|
+
c.should_receive(:destroy)
|
144
|
+
end
|
145
|
+
|
146
|
+
knife.run
|
147
|
+
end
|
148
|
+
end
|
71
149
|
end
|
72
150
|
|
73
|
-
|
74
|
-
|
75
|
-
|
151
|
+
describe "with some clients" do
|
152
|
+
let(:name_args) { [ "^ti" ] }
|
153
|
+
|
154
|
+
it "should only delete clients that match the regex" do
|
155
|
+
clients["tim"].should_receive(:destroy)
|
156
|
+
clients["stephen"].should_not_receive(:destroy)
|
157
|
+
clients["dan"].should_not_receive(:destroy)
|
158
|
+
clients["myorg-validator"].should_not_receive(:destroy)
|
159
|
+
knife.run
|
160
|
+
end
|
76
161
|
end
|
77
162
|
end
|
78
163
|
end
|
@@ -23,7 +23,7 @@ describe Chef::Knife::ClientDelete do
|
|
23
23
|
@knife = Chef::Knife::ClientDelete.new
|
24
24
|
# defaults
|
25
25
|
@knife.config = {
|
26
|
-
:
|
26
|
+
:delete_validators => false
|
27
27
|
}
|
28
28
|
@knife.name_args = [ 'adam' ]
|
29
29
|
end
|
@@ -51,7 +51,7 @@ describe Chef::Knife::ClientDelete do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'should delete non-validator client if --force is not set' do
|
54
|
-
@knife.config[:
|
54
|
+
@knife.config[:delete_validators] = false
|
55
55
|
@client.should_receive(:destroy).and_return(@client)
|
56
56
|
@knife.should_receive(:msg)
|
57
57
|
|
@@ -59,7 +59,7 @@ describe Chef::Knife::ClientDelete do
|
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'should delete non-validator client if --force is set' do
|
62
|
-
@knife.config[:
|
62
|
+
@knife.config[:delete_validators] = true
|
63
63
|
@client.should_receive(:destroy).and_return(@client)
|
64
64
|
@knife.should_receive(:msg)
|
65
65
|
|
@@ -73,7 +73,7 @@ describe Chef::Knife::ClientDelete do
|
|
73
73
|
end
|
74
74
|
|
75
75
|
it 'should delete validator client if --force is set' do
|
76
|
-
@knife.config[:
|
76
|
+
@knife.config[:delete_validators] = true
|
77
77
|
@client.should_receive(:destroy).and_return(@client)
|
78
78
|
@knife.should_receive(:msg)
|
79
79
|
|
@@ -23,178 +23,271 @@ require 'chef/cookbook_uploader'
|
|
23
23
|
require 'timeout'
|
24
24
|
|
25
25
|
describe Chef::Knife::CookbookUpload do
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
let(:cookbook) { Chef::CookbookVersion.new('test_cookbook') }
|
27
|
+
|
28
|
+
let(:cookbooks_by_name) do
|
29
|
+
{cookbook.name => cookbook}
|
30
|
+
end
|
29
31
|
|
30
|
-
|
32
|
+
let(:cookbook_loader) do
|
33
|
+
cookbook_loader = cookbooks_by_name.dup
|
34
|
+
cookbook_loader.stub(:merged_cookbooks).and_return([])
|
35
|
+
cookbook_loader.stub(:load_cookbooks).and_return(cookbook_loader)
|
36
|
+
cookbook_loader
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:cookbook_uploader) { double(:upload_cookbooks => nil) }
|
31
40
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
@cookbook_loader.stub(:load_cookbooks).and_return(@cookbook_loader)
|
36
|
-
Chef::CookbookLoader.stub(:new).and_return(@cookbook_loader)
|
41
|
+
let(:output) { StringIO.new }
|
42
|
+
|
43
|
+
let(:name_args) { ['test_cookbook'] }
|
37
44
|
|
38
|
-
|
39
|
-
|
40
|
-
|
45
|
+
let(:knife) do
|
46
|
+
k = Chef::Knife::CookbookUpload.new
|
47
|
+
k.name_args = name_args
|
48
|
+
k.ui.stub(:stdout).and_return(output)
|
49
|
+
k.ui.stub(:stderr).and_return(output)
|
50
|
+
k
|
51
|
+
end
|
52
|
+
|
53
|
+
before(:each) do
|
54
|
+
Chef::CookbookLoader.stub(:new).and_return(cookbook_loader)
|
41
55
|
end
|
42
56
|
|
43
57
|
describe 'with --concurrency' do
|
44
58
|
it 'should upload cookbooks with predefined concurrency' do
|
45
|
-
@cookbook_uploader = double(:upload_cookbooks => nil)
|
46
59
|
Chef::CookbookVersion.stub(:list_all_versions).and_return({})
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
60
|
+
knife.config[:concurrency] = 3
|
61
|
+
test_cookbook = Chef::CookbookVersion.new('test_cookbook')
|
62
|
+
cookbook_loader.stub(:each).and_yield("test_cookbook", test_cookbook)
|
63
|
+
cookbook_loader.stub(:cookbook_names).and_return(["test_cookbook"])
|
51
64
|
Chef::CookbookUploader.should_receive(:new).with( kind_of(Array), kind_of(Array),
|
52
65
|
{:force=>nil, :concurrency => 3}).and_return(double("Chef::CookbookUploader", :upload_cookbooks=> true))
|
53
|
-
|
66
|
+
knife.run
|
54
67
|
end
|
55
68
|
end
|
56
69
|
|
57
70
|
describe 'run' do
|
58
71
|
before(:each) do
|
59
|
-
|
60
|
-
Chef::CookbookUploader.stub(:new => @cookbook_uploader)
|
72
|
+
Chef::CookbookUploader.stub(:new => cookbook_uploader)
|
61
73
|
Chef::CookbookVersion.stub(:list_all_versions).and_return({})
|
62
74
|
end
|
63
75
|
|
64
76
|
it 'should print usage and exit when a cookbook name is not provided' do
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
lambda {
|
77
|
+
knife.name_args = []
|
78
|
+
knife.should_receive(:show_usage)
|
79
|
+
knife.ui.should_receive(:fatal)
|
80
|
+
lambda { knife.run }.should raise_error(SystemExit)
|
69
81
|
end
|
70
82
|
|
71
83
|
describe 'when specifying a cookbook name' do
|
72
84
|
it 'should upload the cookbook' do
|
73
|
-
|
74
|
-
|
85
|
+
knife.should_receive(:upload).once
|
86
|
+
knife.run
|
75
87
|
end
|
76
88
|
|
77
89
|
it 'should report on success' do
|
78
|
-
|
79
|
-
|
80
|
-
|
90
|
+
knife.should_receive(:upload).once
|
91
|
+
knife.ui.should_receive(:info).with(/Uploaded 1 cookbook/)
|
92
|
+
knife.run
|
81
93
|
end
|
82
94
|
end
|
83
95
|
|
84
96
|
describe 'when specifying the same cookbook name twice' do
|
85
97
|
it 'should upload the cookbook only once' do
|
86
|
-
|
87
|
-
|
88
|
-
|
98
|
+
knife.name_args = ['test_cookbook', 'test_cookbook']
|
99
|
+
knife.should_receive(:upload).once
|
100
|
+
knife.run
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "when uploading a cookbook that uses deprecated overlays" do
|
105
|
+
|
106
|
+
before do
|
107
|
+
cookbook_loader.stub(:merged_cookbooks).and_return(['test_cookbook'])
|
108
|
+
cookbook_loader.stub(:merged_cookbook_paths).
|
109
|
+
and_return({'test_cookbook' => %w{/path/one/test_cookbook /path/two/test_cookbook}})
|
110
|
+
end
|
111
|
+
|
112
|
+
it "emits a warning" do
|
113
|
+
knife.run
|
114
|
+
expected_message=<<-E
|
115
|
+
WARNING: The cookbooks: test_cookbook exist in multiple places in your cookbook_path.
|
116
|
+
A composite version of these cookbooks has been compiled for uploading.
|
117
|
+
|
118
|
+
IMPORTANT: In a future version of Chef, this behavior will be removed and you will no longer
|
119
|
+
be able to have the same version of a cookbook in multiple places in your cookbook_path.
|
120
|
+
WARNING: The affected cookbooks are located:
|
121
|
+
test_cookbook:
|
122
|
+
/path/one/test_cookbook
|
123
|
+
/path/two/test_cookbook
|
124
|
+
E
|
125
|
+
output.string.should include(expected_message)
|
89
126
|
end
|
90
127
|
end
|
91
128
|
|
92
129
|
describe 'when specifying a cookbook name among many' do
|
93
|
-
|
94
|
-
|
95
|
-
|
130
|
+
let(:name_args) { ['test_cookbook1'] }
|
131
|
+
|
132
|
+
let(:cookbooks_by_name) do
|
133
|
+
{
|
96
134
|
'test_cookbook1' => Chef::CookbookVersion.new('test_cookbook1'),
|
97
135
|
'test_cookbook2' => Chef::CookbookVersion.new('test_cookbook2'),
|
98
136
|
'test_cookbook3' => Chef::CookbookVersion.new('test_cookbook3')
|
99
137
|
}
|
100
|
-
@cookbook_loader = {}
|
101
|
-
@cookbook_loader.stub(:merged_cookbooks).and_return([])
|
102
|
-
@cookbook_loader.stub(:[]) { |ckbk| @cookbooks[ckbk] }
|
103
|
-
Chef::CookbookLoader.stub(:new).and_return(@cookbook_loader)
|
104
138
|
end
|
105
139
|
|
106
140
|
it "should read only one cookbook" do
|
107
|
-
|
108
|
-
|
141
|
+
cookbook_loader.should_receive(:[]).once.with('test_cookbook1').and_call_original
|
142
|
+
knife.run
|
109
143
|
end
|
110
144
|
|
111
145
|
it "should not read all cookbooks" do
|
112
|
-
|
113
|
-
|
146
|
+
cookbook_loader.should_not_receive(:load_cookbooks)
|
147
|
+
knife.run
|
114
148
|
end
|
115
149
|
|
116
150
|
it "should upload only one cookbook" do
|
117
|
-
|
118
|
-
|
151
|
+
knife.should_receive(:upload).exactly(1).times
|
152
|
+
knife.run
|
119
153
|
end
|
120
154
|
end
|
121
155
|
|
122
156
|
# This is testing too much. We should break it up.
|
123
157
|
describe 'when specifying a cookbook name with dependencies' do
|
158
|
+
let(:name_args) { ["test_cookbook2"] }
|
159
|
+
|
160
|
+
let(:cookbooks_by_name) do
|
161
|
+
{ "test_cookbook1" => test_cookbook1,
|
162
|
+
"test_cookbook2" => test_cookbook2,
|
163
|
+
"test_cookbook3" => test_cookbook3 }
|
164
|
+
end
|
165
|
+
|
166
|
+
let(:test_cookbook1) { Chef::CookbookVersion.new('test_cookbook1') }
|
167
|
+
|
168
|
+
let(:test_cookbook2) do
|
169
|
+
c = Chef::CookbookVersion.new('test_cookbook2')
|
170
|
+
c.metadata.depends("test_cookbook3")
|
171
|
+
c
|
172
|
+
end
|
173
|
+
|
174
|
+
let(:test_cookbook3) do
|
175
|
+
c = Chef::CookbookVersion.new('test_cookbook3')
|
176
|
+
c.metadata.depends("test_cookbook1")
|
177
|
+
c.metadata.depends("test_cookbook2")
|
178
|
+
c
|
179
|
+
end
|
180
|
+
|
124
181
|
it "should upload all dependencies once" do
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
@test_cookbook3.metadata.depends("test_cookbook2")
|
133
|
-
@cookbook_loader.stub(:[]) do |ckbk|
|
134
|
-
{ "test_cookbook1" => @test_cookbook1,
|
135
|
-
"test_cookbook2" => @test_cookbook2,
|
136
|
-
"test_cookbook3" => @test_cookbook3 }[ckbk]
|
137
|
-
end
|
138
|
-
@knife.stub(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2", "test_cookbook3"])
|
139
|
-
@knife.should_receive(:upload).exactly(3).times
|
140
|
-
Timeout::timeout(5) do
|
141
|
-
@knife.run
|
182
|
+
knife.config[:depends] = true
|
183
|
+
knife.stub(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2", "test_cookbook3"])
|
184
|
+
knife.should_receive(:upload).exactly(3).times
|
185
|
+
lambda do
|
186
|
+
Timeout::timeout(5) do
|
187
|
+
knife.run
|
188
|
+
end
|
142
189
|
end.should_not raise_error
|
143
190
|
end
|
144
191
|
end
|
145
192
|
|
193
|
+
describe 'when specifying a cookbook name with missing dependencies' do
|
194
|
+
let(:cookbook_dependency) { Chef::CookbookVersion.new('dependency') }
|
195
|
+
|
196
|
+
before(:each) do
|
197
|
+
cookbook.metadata.depends("dependency")
|
198
|
+
cookbook_loader.stub(:[]) do |ckbk|
|
199
|
+
{ "test_cookbook" => cookbook,
|
200
|
+
"dependency" => cookbook_dependency}[ckbk]
|
201
|
+
end
|
202
|
+
knife.stub(:cookbook_names).and_return(["cookbook_dependency", "test_cookbook"])
|
203
|
+
@stdout, @stderr, @stdin = StringIO.new, StringIO.new, StringIO.new
|
204
|
+
knife.ui = Chef::Knife::UI.new(@stdout, @stderr, @stdin, {})
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'should exit and not upload the cookbook' do
|
208
|
+
cookbook_loader.should_receive(:[]).once.with('test_cookbook')
|
209
|
+
cookbook_loader.should_not_receive(:load_cookbooks)
|
210
|
+
cookbook_uploader.should_not_receive(:upload_cookbooks)
|
211
|
+
expect {knife.run}.to raise_error(SystemExit)
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'should output a message for a single missing dependency' do
|
215
|
+
expect {knife.run}.to raise_error(SystemExit)
|
216
|
+
@stderr.string.should include('Cookbook test_cookbook depends on cookbooks which are not currently')
|
217
|
+
@stderr.string.should include('being uploaded and cannot be found on the server.')
|
218
|
+
@stderr.string.should include("The missing cookbook(s) are: 'dependency' version '>= 0.0.0'")
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'should output a message for a multiple missing dependencies which are concatenated' do
|
222
|
+
cookbook_dependency2 = Chef::CookbookVersion.new('dependency2')
|
223
|
+
cookbook.metadata.depends("dependency2")
|
224
|
+
cookbook_loader.stub(:[]) do |ckbk|
|
225
|
+
{ "test_cookbook" => cookbook,
|
226
|
+
"dependency" => cookbook_dependency,
|
227
|
+
"dependency2" => cookbook_dependency2}[ckbk]
|
228
|
+
end
|
229
|
+
knife.stub(:cookbook_names).and_return(["dependency", "dependency2", "test_cookbook"])
|
230
|
+
expect {knife.run}.to raise_error(SystemExit)
|
231
|
+
@stderr.string.should include('Cookbook test_cookbook depends on cookbooks which are not currently')
|
232
|
+
@stderr.string.should include('being uploaded and cannot be found on the server.')
|
233
|
+
@stderr.string.should include("The missing cookbook(s) are:")
|
234
|
+
@stderr.string.should include("'dependency' version '>= 0.0.0'")
|
235
|
+
@stderr.string.should include("'dependency2' version '>= 0.0.0'")
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
146
239
|
it "should freeze the version of the cookbooks if --freeze is specified" do
|
147
|
-
|
148
|
-
|
149
|
-
|
240
|
+
knife.config[:freeze] = true
|
241
|
+
cookbook.should_receive(:freeze_version).once
|
242
|
+
knife.run
|
150
243
|
end
|
151
244
|
|
152
245
|
describe 'with -a or --all' do
|
153
246
|
before(:each) do
|
154
|
-
|
247
|
+
knife.config[:all] = true
|
155
248
|
@test_cookbook1 = Chef::CookbookVersion.new('test_cookbook1')
|
156
249
|
@test_cookbook2 = Chef::CookbookVersion.new('test_cookbook2')
|
157
|
-
|
158
|
-
|
250
|
+
cookbook_loader.stub(:each).and_yield("test_cookbook1", @test_cookbook1).and_yield("test_cookbook2", @test_cookbook2)
|
251
|
+
cookbook_loader.stub(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2"])
|
159
252
|
end
|
160
253
|
|
161
254
|
it 'should upload all cookbooks' do
|
162
|
-
|
163
|
-
|
255
|
+
knife.should_receive(:upload).once
|
256
|
+
knife.run
|
164
257
|
end
|
165
258
|
|
166
259
|
it 'should report on success' do
|
167
|
-
|
168
|
-
|
169
|
-
|
260
|
+
knife.should_receive(:upload).once
|
261
|
+
knife.ui.should_receive(:info).with(/Uploaded all cookbooks/)
|
262
|
+
knife.run
|
170
263
|
end
|
171
264
|
|
172
265
|
it 'should update the version constraints for an environment' do
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
266
|
+
knife.stub(:assert_environment_valid!).and_return(true)
|
267
|
+
knife.config[:environment] = "production"
|
268
|
+
knife.should_receive(:update_version_constraints).once
|
269
|
+
knife.run
|
177
270
|
end
|
178
271
|
end
|
179
272
|
|
180
273
|
describe 'when a frozen cookbook exists on the server' do
|
181
274
|
it 'should fail to replace it' do
|
182
275
|
exception = Chef::Exceptions::CookbookFrozen.new
|
183
|
-
|
276
|
+
cookbook_uploader.should_receive(:upload_cookbooks).
|
184
277
|
and_raise(exception)
|
185
|
-
|
186
|
-
|
187
|
-
lambda {
|
278
|
+
knife.ui.stub(:error)
|
279
|
+
knife.ui.should_receive(:error).with(exception)
|
280
|
+
lambda { knife.run }.should raise_error(SystemExit)
|
188
281
|
end
|
189
282
|
|
190
283
|
it 'should not update the version constraints for an environment' do
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
lambda {
|
284
|
+
knife.stub(:assert_environment_valid!).and_return(true)
|
285
|
+
knife.config[:environment] = "production"
|
286
|
+
knife.stub(:upload).and_raise(Chef::Exceptions::CookbookFrozen)
|
287
|
+
knife.ui.should_receive(:error).with(/Failed to upload 1 cookbook/)
|
288
|
+
knife.ui.should_receive(:warn).with(/Not updating version constraints/)
|
289
|
+
knife.should_not_receive(:update_version_constraints)
|
290
|
+
lambda { knife.run }.should raise_error(SystemExit)
|
198
291
|
end
|
199
292
|
end
|
200
293
|
end # run
|