chef 11.16.4-x86-mingw32 → 11.18.0-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/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
@@ -0,0 +1,63 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Ryan Cragun (<ryan@getchef.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'spec_helper'
|
20
|
+
require 'lib/chef/chef_fs/data_handler/group_data_handler'
|
21
|
+
|
22
|
+
class TestEntry < Mash
|
23
|
+
attr_accessor :name, :org
|
24
|
+
|
25
|
+
def initialize(name, org)
|
26
|
+
@name = name
|
27
|
+
@org = org
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe Chef::ChefFS::DataHandler::GroupDataHandler do
|
32
|
+
describe '#normalize_for_post' do
|
33
|
+
let(:entry) do
|
34
|
+
TestEntry.new('workers.json', 'hive')
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:group) do
|
38
|
+
{ 'name' => 'worker_bees',
|
39
|
+
'clients' => %w(honey sting),
|
40
|
+
'users' => %w(fizz buzz),
|
41
|
+
'actors' => %w(honey)
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:normalized) do
|
46
|
+
{ 'actors' =>
|
47
|
+
{ 'users' => %w(fizz buzz),
|
48
|
+
'clients'=> %w(honey sting),
|
49
|
+
'groups'=> []
|
50
|
+
},
|
51
|
+
'groupname' => 'workers',
|
52
|
+
'name' => 'worker_bees',
|
53
|
+
'orgname' => 'hive'
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
let(:handler) { described_class.new }
|
58
|
+
|
59
|
+
it 'normalizes the users, clients and groups into actors' do
|
60
|
+
expect(handler.normalize_for_post(group, entry)).to eq(normalized)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'chef/config_fetcher'
|
3
3
|
describe Chef::ConfigFetcher do
|
4
|
-
let(:valid_json) { {:a=>"b"}
|
4
|
+
let(:valid_json) { Chef::JSONCompat.to_json({:a=>"b"}) }
|
5
5
|
let(:invalid_json) { %q[{"syntax-error": "missing quote}] }
|
6
6
|
let(:http) { double("Chef::HTTP::Simple") }
|
7
7
|
|
@@ -582,7 +582,7 @@ describe Chef::Cookbook::Metadata do
|
|
582
582
|
@meta.version "1.2.3"
|
583
583
|
end
|
584
584
|
|
585
|
-
describe "
|
585
|
+
describe "#to_json" do
|
586
586
|
before(:each) do
|
587
587
|
@serial = Chef::JSONCompat.from_json(@meta.to_json)
|
588
588
|
end
|
@@ -613,11 +613,15 @@ describe Chef::Cookbook::Metadata do
|
|
613
613
|
@serial[t].should == @meta.send(t.to_sym)
|
614
614
|
end
|
615
615
|
end
|
616
|
+
|
617
|
+
it "should produce the same output from to_json and Chef::JSONCompat" do
|
618
|
+
expect(@meta.to_json).to eq(Chef::JSONCompat.to_json(@meta))
|
619
|
+
end
|
616
620
|
end
|
617
621
|
|
618
|
-
describe "
|
622
|
+
describe "::from_json" do
|
619
623
|
before(:each) do
|
620
|
-
@deserial = Chef::Cookbook::Metadata.from_json(@meta
|
624
|
+
@deserial = Chef::Cookbook::Metadata.from_json(Chef::JSONCompat.to_json(@meta))
|
621
625
|
end
|
622
626
|
|
623
627
|
it "should deserialize to a Chef::Cookbook::Metadata object" do
|
@@ -181,7 +181,7 @@ describe Chef::CookbookLoader do
|
|
181
181
|
aa.to_hash["metadata"].recipes.keys.should include("openldap")
|
182
182
|
expected_desc = "Main Open LDAP configuration"
|
183
183
|
aa.to_hash["metadata"].recipes["openldap"].should == expected_desc
|
184
|
-
raw = aa.to_hash["metadata"].recipes
|
184
|
+
raw = Chef::JSONCompat.to_json(aa.to_hash["metadata"].recipes)
|
185
185
|
search_str = "\"openldap\":\""
|
186
186
|
key_idx = raw.index(search_str)
|
187
187
|
key_idx.should be > 0
|
@@ -166,7 +166,7 @@ describe Chef::DataBagItem do
|
|
166
166
|
before(:each) do
|
167
167
|
@data_bag_item.data_bag('mars_volta')
|
168
168
|
@data_bag_item.raw_data = { "id" => "octahedron", "snooze" => { "finally" => :world_will }}
|
169
|
-
@deserial = Chef::JSONCompat.from_json(@data_bag_item
|
169
|
+
@deserial = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(@data_bag_item))
|
170
170
|
end
|
171
171
|
|
172
172
|
it "should deserialize to a Chef::DataBagItem object" do
|
@@ -184,6 +184,10 @@ describe Chef::DataBagItem do
|
|
184
184
|
it "should have a matching 'snooze' key" do
|
185
185
|
@deserial["snooze"].should == { "finally" => "world_will" }
|
186
186
|
end
|
187
|
+
|
188
|
+
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
|
189
|
+
let(:subject) { @data_bag_item }
|
190
|
+
end
|
187
191
|
end
|
188
192
|
|
189
193
|
describe "when converting to a string" do
|
data/spec/unit/data_bag_spec.rb
CHANGED
@@ -58,7 +58,7 @@ describe Chef::DataBag do
|
|
58
58
|
describe "deserialize" do
|
59
59
|
before(:each) do
|
60
60
|
@data_bag.name('mars_volta')
|
61
|
-
@deserial = Chef::JSONCompat.from_json(@data_bag
|
61
|
+
@deserial = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(@data_bag))
|
62
62
|
end
|
63
63
|
|
64
64
|
it "should deserialize to a Chef::DataBag object" do
|
@@ -73,6 +73,10 @@ describe Chef::DataBag do
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
+
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
|
77
|
+
let(:subject) { @data_bag }
|
78
|
+
end
|
79
|
+
|
76
80
|
end
|
77
81
|
|
78
82
|
describe "when saving" do
|
@@ -46,7 +46,7 @@ describe Chef::Deprecation do
|
|
46
46
|
end
|
47
47
|
|
48
48
|
method_snapshot_file = File.join(CHEF_SPEC_DATA, "file-providers-method-snapshot-chef-11-4.json")
|
49
|
-
method_snapshot =
|
49
|
+
method_snapshot = Chef::JSONCompat.parse(File.open(method_snapshot_file).read())
|
50
50
|
|
51
51
|
method_snapshot.each do |class_name, old_methods|
|
52
52
|
class_object = class_from_string(class_name)
|
@@ -100,6 +100,17 @@ describe Chef::EncryptedDataBagItem::Decryptor do
|
|
100
100
|
let(:plaintext_data) { {"foo" => "bar"} }
|
101
101
|
let(:encryption_key) { "passwd" }
|
102
102
|
let(:decryption_key) { encryption_key }
|
103
|
+
let(:json_wrapped_data) { Chef::JSONCompat.to_json({"json_wrapper" => plaintext_data}) }
|
104
|
+
|
105
|
+
shared_examples "decryption examples" do
|
106
|
+
it "decrypts the encrypted value" do
|
107
|
+
decryptor.decrypted_data.should eq(json_wrapped_data)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "unwraps the encrypted data and returns it" do
|
111
|
+
decryptor.for_decrypted_item.should eq plaintext_data
|
112
|
+
end
|
113
|
+
end
|
103
114
|
|
104
115
|
context "when decrypting a version 2 (JSON+aes-256-cbc+hmac-sha256+random iv) encrypted value" do
|
105
116
|
let(:encrypted_value) do
|
@@ -112,6 +123,8 @@ describe Chef::EncryptedDataBagItem::Decryptor do
|
|
112
123
|
Base64.encode64(raw_hmac)
|
113
124
|
end
|
114
125
|
|
126
|
+
include_examples "decryption examples"
|
127
|
+
|
115
128
|
it "rejects the data if the hmac is wrong" do
|
116
129
|
encrypted_value["hmac"] = bogus_hmac
|
117
130
|
lambda { decryptor.for_decrypted_item }.should raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
|
@@ -134,13 +147,7 @@ describe Chef::EncryptedDataBagItem::Decryptor do
|
|
134
147
|
decryptor.should be_a_kind_of Chef::EncryptedDataBagItem::Decryptor::Version1Decryptor
|
135
148
|
end
|
136
149
|
|
137
|
-
|
138
|
-
decryptor.decrypted_data.should eq({"json_wrapper" => plaintext_data}.to_json)
|
139
|
-
end
|
140
|
-
|
141
|
-
it "unwraps the encrypted data and returns it" do
|
142
|
-
decryptor.for_decrypted_item.should eq plaintext_data
|
143
|
-
end
|
150
|
+
include_examples "decryption examples"
|
144
151
|
|
145
152
|
describe "and the decryption step returns invalid data" do
|
146
153
|
it "raises a decryption failure error" do
|
@@ -196,7 +196,7 @@ describe Chef::Environment do
|
|
196
196
|
|
197
197
|
%w{name description cookbook_versions}.each do |t|
|
198
198
|
it "should include '#{t}'" do
|
199
|
-
@json.should =~ /"#{t}":#{Regexp.escape(@environment.send(t.to_sym)
|
199
|
+
@json.should =~ /"#{t}":#{Regexp.escape(Chef::JSONCompat.to_json(@environment.send(t.to_sym)))}/
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|
@@ -207,6 +207,10 @@ describe Chef::Environment do
|
|
207
207
|
it "should include 'chef_type'" do
|
208
208
|
@json.should =~ /"chef_type":"environment"/
|
209
209
|
end
|
210
|
+
|
211
|
+
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
|
212
|
+
let(:subject) { @environment }
|
213
|
+
end
|
210
214
|
end
|
211
215
|
|
212
216
|
describe "from_json" do
|
@@ -222,7 +226,7 @@ describe Chef::Environment do
|
|
222
226
|
"json_class" => "Chef::Environment",
|
223
227
|
"chef_type" => "environment"
|
224
228
|
}
|
225
|
-
@environment = Chef::JSONCompat.from_json(@data
|
229
|
+
@environment = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(@data))
|
226
230
|
end
|
227
231
|
|
228
232
|
it "should return a Chef::Environment" do
|
@@ -420,7 +424,7 @@ describe Chef::Environment do
|
|
420
424
|
"description" => "desc",
|
421
425
|
"chef_type" => "environment"
|
422
426
|
}
|
423
|
-
IO.should_receive(:read).with(File.join(Chef::Config[:environment_path], 'foo.json')).and_return(
|
427
|
+
IO.should_receive(:read).with(File.join(Chef::Config[:environment_path], 'foo.json')).and_return(Chef::JSONCompat.to_json(environment_hash))
|
424
428
|
environment = Chef::Environment.load('foo')
|
425
429
|
|
426
430
|
environment.should be_a_kind_of(Chef::Environment)
|
@@ -74,5 +74,11 @@ describe Chef::Exceptions do
|
|
74
74
|
it "should have an exception class of #{exception} which inherits from #{expected_super_class}" do
|
75
75
|
lambda{ raise exception }.should raise_error(expected_super_class)
|
76
76
|
end
|
77
|
+
|
78
|
+
if exception.methods.include?(:to_json)
|
79
|
+
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
|
80
|
+
let(:subject) { exception }
|
81
|
+
end
|
82
|
+
end
|
77
83
|
end
|
78
84
|
end
|
@@ -21,49 +21,90 @@ require 'chef/json_compat'
|
|
21
21
|
|
22
22
|
describe Chef::JSONCompat do
|
23
23
|
|
24
|
-
describe "with JSON containing an existing class" do
|
25
|
-
let(:json){'{"json_class": "Chef::Role"}'}
|
24
|
+
describe "#from_json with JSON containing an existing class" do
|
25
|
+
let(:json) { '{"json_class": "Chef::Role"}' }
|
26
|
+
|
26
27
|
it "returns an instance of the class instead of a Hash" do
|
27
|
-
Chef::JSONCompat.from_json(json).class.
|
28
|
+
expect(Chef::JSONCompat.from_json(json).class).to eq Chef::Role
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#from_json with JSON containing comments" do
|
33
|
+
let(:json) { %Q{{\n/* comment */\n// comment 2\n"json_class": "Chef::Role"}} }
|
34
|
+
|
35
|
+
it "returns an instance of the class instead of a Hash" do
|
36
|
+
expect(Chef::JSONCompat.from_json(json).class).to eq Chef::Role
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#parse with JSON containing comments" do
|
41
|
+
let(:json) { %Q{{\n/* comment */\n// comment 2\n"json_class": "Chef::Role"}} }
|
42
|
+
|
43
|
+
it "returns a Hash" do
|
44
|
+
expect(Chef::JSONCompat.parse(json).class).to eq Hash
|
28
45
|
end
|
29
46
|
end
|
30
47
|
|
31
48
|
describe 'with JSON containing "Chef::Sandbox" as a json_class value' do
|
32
49
|
require 'chef/sandbox' # Only needed for this test
|
33
|
-
|
50
|
+
|
51
|
+
let(:json) { '{"json_class": "Chef::Sandbox", "arbitrary": "data"}' }
|
52
|
+
|
34
53
|
it "returns a Hash, because Chef::Sandbox is a dummy class" do
|
35
|
-
Chef::JSONCompat.from_json(json).
|
54
|
+
expect(Chef::JSONCompat.from_json(json)).to eq({"json_class" => "Chef::Sandbox", "arbitrary" => "data"})
|
36
55
|
end
|
37
56
|
end
|
38
57
|
|
39
|
-
describe "
|
40
|
-
|
41
|
-
|
42
|
-
|
58
|
+
describe "when pretty printing an object that defines #to_json" do
|
59
|
+
class Foo
|
60
|
+
def to_json(*a)
|
61
|
+
Chef::JSONCompat.to_json({'bar' => {'baz' => 5678}}, *a)
|
62
|
+
end
|
43
63
|
end
|
44
64
|
|
65
|
+
it "should work" do
|
66
|
+
f = Foo.new
|
67
|
+
expect(Chef::JSONCompat.to_json_pretty(f)).to eql("{\n \"bar\": {\n \"baz\": 5678\n }\n}\n")
|
68
|
+
end
|
69
|
+
|
70
|
+
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
|
71
|
+
let(:subject) { Foo.new }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "with a file with 300 or less nested entries" do
|
76
|
+
let(:json) { IO.read(File.join(CHEF_SPEC_DATA, 'big_json.json')) }
|
77
|
+
let(:hash) { Chef::JSONCompat.from_json(json) }
|
78
|
+
|
45
79
|
describe "when a big json file is loaded" do
|
46
80
|
it "should create a Hash from the file" do
|
47
|
-
|
81
|
+
expect(hash).to be_kind_of(Hash)
|
48
82
|
end
|
83
|
+
|
49
84
|
it "should has 'test' as a 300th nested value" do
|
50
|
-
|
85
|
+
expect(hash['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']).to eq('test')
|
51
86
|
end
|
52
87
|
end
|
53
88
|
end
|
89
|
+
|
54
90
|
describe "with a file with more than 300 nested entries" do
|
55
|
-
|
56
|
-
|
57
|
-
@hash = Chef::JSONCompat.from_json(@json, {:max_nesting => 301})
|
58
|
-
end
|
91
|
+
let(:json) { IO.read(File.join(CHEF_SPEC_DATA, 'big_json_plus_one.json')) }
|
92
|
+
let(:hash) { Chef::JSONCompat.from_json(json, {:max_nesting => 301}) }
|
59
93
|
|
60
94
|
describe "when a big json file is loaded" do
|
61
95
|
it "should create a Hash from the file" do
|
62
|
-
|
96
|
+
expect(hash).to be_kind_of(Hash)
|
63
97
|
end
|
98
|
+
|
64
99
|
it "should has 'test' as a 301st nested value" do
|
65
|
-
|
100
|
+
expect(hash['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']).to eq('test')
|
66
101
|
end
|
67
102
|
end
|
68
103
|
end
|
104
|
+
|
105
|
+
it "should define .to_json on all classes" do
|
106
|
+
class SomeClass; end
|
107
|
+
|
108
|
+
expect(SomeClass.new.respond_to?(:to_json)).to eq(true)
|
109
|
+
end
|
69
110
|
end
|
@@ -27,7 +27,6 @@ describe Chef::Knife::CookbookMetadataFromFile do
|
|
27
27
|
@tgt = File.expand_path(File.join(CHEF_SPEC_DATA, "metadata", "quick_start", "metadata.json"))
|
28
28
|
@knife = Chef::Knife::CookbookMetadataFromFile.new
|
29
29
|
@knife.name_args = [ @src ]
|
30
|
-
@knife.stub(:to_json_pretty).and_return(true)
|
31
30
|
@md = Chef::Cookbook::Metadata.new
|
32
31
|
Chef::Cookbook::Metadata.stub(:new).and_return(@md)
|
33
32
|
$stdout.stub(:write)
|
@@ -26,7 +26,8 @@ describe Chef::Knife::CookbookSiteDownload do
|
|
26
26
|
@knife.name_args = ['apache2']
|
27
27
|
@noauth_rest = double('no auth rest')
|
28
28
|
@stdout = StringIO.new
|
29
|
-
@
|
29
|
+
@stderr = StringIO.new
|
30
|
+
@cookbook_api_url = 'https://supermarket.getchef.com/api/v1/cookbooks'
|
30
31
|
@version = '1.0.2'
|
31
32
|
@version_us = @version.gsub '.', '_'
|
32
33
|
@current_data = { 'deprecated' => false,
|
@@ -19,132 +19,177 @@
|
|
19
19
|
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
|
20
20
|
|
21
21
|
describe Chef::Knife::CookbookSiteInstall do
|
22
|
+
let(:knife) { Chef::Knife::CookbookSiteInstall.new }
|
23
|
+
let(:stdout) { StringIO.new }
|
24
|
+
let(:stderr) { StringIO.new }
|
25
|
+
let(:downloader) { Hash.new }
|
26
|
+
let(:repo) { double(:sanity_check => true, :reset_to_default_state => true,
|
27
|
+
:prepare_to_import => true, :finalize_updates_to => true,
|
28
|
+
:merge_updates_from => true) }
|
29
|
+
let(:install_path) { if Chef::Platform.windows?
|
30
|
+
'C:/tmp/chef'
|
31
|
+
else
|
32
|
+
'/var/tmp/chef'
|
33
|
+
end }
|
34
|
+
|
22
35
|
before(:each) do
|
23
36
|
require 'chef/knife/core/cookbook_scm_repo'
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
File.stub(:rmtree)
|
43
|
-
@knife.stub(:shell_out!).and_return(true)
|
44
|
-
|
45
|
-
#CookbookSiteDownload Stup
|
46
|
-
@downloader = {}
|
47
|
-
@knife.stub(:download_cookbook_to).and_return(@downloader)
|
48
|
-
@downloader.stub(:version).and_return do
|
49
|
-
if @knife.name_args.size == 2
|
50
|
-
@knife.name_args[1]
|
37
|
+
|
38
|
+
allow(knife.ui).to receive(:stdout).and_return(stdout)
|
39
|
+
knife.config = {}
|
40
|
+
knife.config[:cookbook_path] = [ install_path ]
|
41
|
+
|
42
|
+
allow(knife).to receive(:stderr).and_return(stderr)
|
43
|
+
allow(knife).to receive(:stdout).and_return(stdout)
|
44
|
+
|
45
|
+
# Assume all external commands would have succeed. :(
|
46
|
+
allow(File).to receive(:unlink)
|
47
|
+
allow(File).to receive(:rmtree)
|
48
|
+
allow(knife).to receive(:shell_out!).and_return(true)
|
49
|
+
|
50
|
+
# CookbookSiteDownload Stup
|
51
|
+
allow(knife).to receive(:download_cookbook_to).and_return(downloader)
|
52
|
+
allow(downloader).to receive(:version) do
|
53
|
+
if knife.name_args.size == 2
|
54
|
+
knife.name_args[1]
|
51
55
|
else
|
52
56
|
"0.3.0"
|
53
57
|
end
|
54
58
|
end
|
55
59
|
|
56
|
-
#Stubs for CookbookSCMRepo
|
57
|
-
|
58
|
-
:prepare_to_import => true, :finalize_updates_to => true,
|
59
|
-
:merge_updates_from => true)
|
60
|
-
Chef::Knife::CookbookSCMRepo.stub(:new).and_return(@repo)
|
60
|
+
# Stubs for CookbookSCMRepo
|
61
|
+
allow(Chef::Knife::CookbookSCMRepo).to receive(:new).and_return(repo)
|
61
62
|
end
|
62
63
|
|
63
|
-
|
64
64
|
describe "run" do
|
65
|
-
it "
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
it "
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
end
|
76
|
-
|
77
|
-
it "
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
it "
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
it "
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
94
|
-
|
95
|
-
it "
|
96
|
-
|
97
|
-
|
98
|
-
upstream_file = File.join(
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
end
|
105
|
-
|
106
|
-
it "
|
107
|
-
|
108
|
-
|
109
|
-
upstream_file = File.join(
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
end
|
116
|
-
|
117
|
-
it "
|
118
|
-
|
119
|
-
|
120
|
-
upstream_file = File.join(
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
it "
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
upstream_file = File.join(
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
end
|
137
|
-
|
138
|
-
it "should not raise an error if cookbook_path is a string" do
|
139
|
-
@knife.config[:cookbook_path] = @install_path
|
140
|
-
@knife.config[:no_deps] = true
|
141
|
-
@knife.name_args = ["getting-started"]
|
142
|
-
upstream_file = File.join(@install_path, "getting-started.tar.gz")
|
143
|
-
@knife.should_receive(:download_cookbook_to).with(upstream_file)
|
144
|
-
@knife.should_receive(:extract_cookbook).with(upstream_file, "0.3.0")
|
145
|
-
@knife.should_receive(:clear_existing_files).with(File.join(@install_path, "getting-started"))
|
146
|
-
@repo.should_receive(:merge_updates_from).with("getting-started", "0.3.0")
|
147
|
-
lambda { @knife.run }.should_not raise_error
|
65
|
+
it "raises an error if a cookbook name is not provided" do
|
66
|
+
knife.name_args = []
|
67
|
+
expect(knife.ui).to receive(:error).with("Please specify a cookbook to download and install.")
|
68
|
+
expect { knife.run }.to raise_error(SystemExit)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "raises an error if more than two arguments are given" do
|
72
|
+
knife.name_args = ["foo", "bar", "baz"]
|
73
|
+
expect(knife.ui).to receive(:error).with("Installing multiple cookbooks at once is not supported.")
|
74
|
+
expect { knife.run }.to raise_error(SystemExit)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "raises an error if the second argument is not a version" do
|
78
|
+
knife.name_args = ["getting-started", "1pass"]
|
79
|
+
expect(knife.ui).to receive(:error).with("Installing multiple cookbooks at once is not supported.")
|
80
|
+
expect { knife.run }.to raise_error(SystemExit)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "raises an error if the second argument is a four-digit version" do
|
84
|
+
knife.name_args = ["getting-started", "0.0.0.1"]
|
85
|
+
expect(knife.ui).to receive(:error).with("Installing multiple cookbooks at once is not supported.")
|
86
|
+
expect { knife.run }.to raise_error(SystemExit)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "raises an error if the second argument is a one-digit version" do
|
90
|
+
knife.name_args = ["getting-started", "1"]
|
91
|
+
expect(knife.ui).to receive(:error).with("Installing multiple cookbooks at once is not supported.")
|
92
|
+
expect { knife.run }.to raise_error(SystemExit)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "installs the specified version if second argument is a three-digit version" do
|
96
|
+
knife.name_args = ["getting-started", "0.1.0"]
|
97
|
+
knife.config[:no_deps] = true
|
98
|
+
upstream_file = File.join(install_path, "getting-started.tar.gz")
|
99
|
+
expect(knife).to receive(:download_cookbook_to).with(upstream_file)
|
100
|
+
expect(knife).to receive(:extract_cookbook).with(upstream_file, "0.1.0")
|
101
|
+
expect(knife).to receive(:clear_existing_files).with(File.join(install_path, "getting-started"))
|
102
|
+
expect(repo).to receive(:merge_updates_from).with("getting-started", "0.1.0")
|
103
|
+
knife.run
|
104
|
+
end
|
105
|
+
|
106
|
+
it "installs the specified version if second argument is a two-digit version" do
|
107
|
+
knife.name_args = ["getting-started", "0.1"]
|
108
|
+
knife.config[:no_deps] = true
|
109
|
+
upstream_file = File.join(install_path, "getting-started.tar.gz")
|
110
|
+
expect(knife).to receive(:download_cookbook_to).with(upstream_file)
|
111
|
+
expect(knife).to receive(:extract_cookbook).with(upstream_file, "0.1")
|
112
|
+
expect(knife).to receive(:clear_existing_files).with(File.join(install_path, "getting-started"))
|
113
|
+
expect(repo).to receive(:merge_updates_from).with("getting-started", "0.1")
|
114
|
+
knife.run
|
115
|
+
end
|
116
|
+
|
117
|
+
it "installs the latest version if only a cookbook name is given" do
|
118
|
+
knife.name_args = ["getting-started"]
|
119
|
+
knife.config[:no_deps] = true
|
120
|
+
upstream_file = File.join(install_path, "getting-started.tar.gz")
|
121
|
+
expect(knife).to receive(:download_cookbook_to).with(upstream_file)
|
122
|
+
expect(knife).to receive(:extract_cookbook).with(upstream_file, "0.3.0")
|
123
|
+
expect(knife).to receive(:clear_existing_files).with(File.join(install_path, "getting-started"))
|
124
|
+
expect(repo).to receive(:merge_updates_from).with("getting-started", "0.3.0")
|
125
|
+
knife.run
|
126
|
+
end
|
127
|
+
|
128
|
+
it "does not create/reset git branches if use_current_branch is set" do
|
129
|
+
knife.name_args = ["getting-started"]
|
130
|
+
knife.config[:use_current_branch] = true
|
131
|
+
knife.config[:no_deps] = true
|
132
|
+
upstream_file = File.join(install_path, "getting-started.tar.gz")
|
133
|
+
expect(repo).not_to receive(:prepare_to_import)
|
134
|
+
expect(repo).not_to receive(:reset_to_default_state)
|
135
|
+
knife.run
|
148
136
|
end
|
137
|
+
|
138
|
+
it "does not raise an error if cookbook_path is a string" do
|
139
|
+
knife.config[:cookbook_path] = install_path
|
140
|
+
knife.config[:no_deps] = true
|
141
|
+
knife.name_args = ["getting-started"]
|
142
|
+
upstream_file = File.join(install_path, "getting-started.tar.gz")
|
143
|
+
expect(knife).to receive(:download_cookbook_to).with(upstream_file)
|
144
|
+
expect(knife).to receive(:extract_cookbook).with(upstream_file, "0.3.0")
|
145
|
+
expect(knife).to receive(:clear_existing_files).with(File.join(install_path, "getting-started"))
|
146
|
+
expect(repo).to receive(:merge_updates_from).with("getting-started", "0.3.0")
|
147
|
+
expect { knife.run }.not_to raise_error
|
148
|
+
end
|
149
|
+
end # end of run
|
150
|
+
|
151
|
+
let(:metadata) { Chef::Cookbook::Metadata.new }
|
152
|
+
let(:rb_metadata_path) { File.join(install_path, "post-punk-kitchen", "metadata.rb") }
|
153
|
+
let(:json_metadata_path) { File.join(install_path, "post-punk-kitchen", "metadata.json") }
|
154
|
+
|
155
|
+
describe "preferred_metadata" do
|
156
|
+
before do
|
157
|
+
allow(Chef::Cookbook::Metadata).to receive(:new).and_return(metadata)
|
158
|
+
allow(File).to receive(:exist?).and_return(false)
|
159
|
+
knife.instance_variable_set(:@cookbook_name, "post-punk-kitchen")
|
160
|
+
knife.instance_variable_set(:@install_path, install_path)
|
161
|
+
end
|
162
|
+
|
163
|
+
it "returns a populated Metadata object if metadata.rb exists" do
|
164
|
+
allow(File).to receive(:exist?).with(rb_metadata_path).and_return(true)
|
165
|
+
expect(metadata).to receive(:from_file).with(rb_metadata_path)
|
166
|
+
knife.preferred_metadata
|
167
|
+
end
|
168
|
+
|
169
|
+
it "returns a populated Metadata object if metadata.json exists" do
|
170
|
+
allow(File).to receive(:exist?).with(json_metadata_path).and_return(true)
|
171
|
+
#expect(IO).to receive(:read).with(json_metadata_path)
|
172
|
+
allow(IO).to receive(:read)
|
173
|
+
expect(metadata).to receive(:from_json)
|
174
|
+
knife.preferred_metadata
|
175
|
+
end
|
176
|
+
|
177
|
+
it "prefers metadata.rb over metadata.json" do
|
178
|
+
allow(File).to receive(:exist?).with(rb_metadata_path).and_return(true)
|
179
|
+
allow(File).to receive(:exist?).with(json_metadata_path).and_return(true)
|
180
|
+
allow(IO).to receive(:read)
|
181
|
+
expect(metadata).to receive(:from_file).with(rb_metadata_path)
|
182
|
+
expect(metadata).not_to receive(:from_json)
|
183
|
+
knife.preferred_metadata
|
184
|
+
end
|
185
|
+
|
186
|
+
it "rasies an error if it finds no metadata file" do
|
187
|
+
expect { knife.preferred_metadata }.to raise_error { |error|
|
188
|
+
expect(error).to be_a(Chef::Exceptions::MetadataNotFound)
|
189
|
+
expect(error.cookbook_name).to eq("post-punk-kitchen")
|
190
|
+
expect(error.install_path).to eq(install_path)
|
191
|
+
}
|
192
|
+
end
|
193
|
+
|
149
194
|
end
|
150
195
|
end
|