chef 12.9.41-universal-mingw32 → 12.10.24-universal-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +52 -13
- data/README.md +145 -0
- data/Rakefile +4 -14
- data/VERSION +1 -1
- data/acceptance/.gitignore +0 -1
- data/acceptance/Gemfile +2 -2
- data/acceptance/Gemfile.lock +235 -0
- data/acceptance/fips/.kitchen.yml +5 -1
- data/acceptance/fips/test/integration/{fips → fips-integration}/serverspec/Gemfile +0 -0
- data/acceptance/fips/test/integration/fips-integration/serverspec/fips-integration_spec.rb +51 -0
- data/acceptance/fips/test/integration/fips-unit-functional/serverspec/Gemfile +3 -0
- data/acceptance/fips/test/integration/fips-unit-functional/serverspec/fips-unit-functional_spec.rb +56 -0
- data/{chef-windows.gemspec → chef-universal-mingw32.gemspec} +0 -0
- data/chef.gemspec +0 -6
- data/{lib → lib-backcompat}/chef/chef_fs/file_system/already_exists_error.rb +0 -0
- data/{lib → lib-backcompat}/chef/chef_fs/file_system/cookbook_frozen_error.rb +0 -0
- data/{lib → lib-backcompat}/chef/chef_fs/file_system/default_environment_cannot_be_modified_error.rb +0 -0
- data/{lib → lib-backcompat}/chef/chef_fs/file_system/file_system_error.rb +0 -0
- data/{lib → lib-backcompat}/chef/chef_fs/file_system/must_delete_recursively_error.rb +0 -0
- data/{lib → lib-backcompat}/chef/chef_fs/file_system/not_found_error.rb +0 -0
- data/{lib → lib-backcompat}/chef/chef_fs/file_system/operation_failed_error.rb +0 -0
- data/{lib → lib-backcompat}/chef/chef_fs/file_system/operation_not_allowed_error.rb +0 -0
- data/lib-backcompat/chef/chef_fs/file_system/repository/chef_repository_file_system_acls_dir.rb +5 -0
- data/lib-backcompat/chef/chef_fs/file_system/repository/chef_repository_file_system_client_keys_dir.rb +5 -0
- data/lib-backcompat/chef/chef_fs/file_system/repository/chef_repository_file_system_entry.rb +6 -0
- data/lib-backcompat/chef/chef_fs/file_system/repository/chef_repository_file_system_policies_dir.rb +5 -0
- data/{lib → lib-backcompat}/chef/chef_fs/file_system/repository/file_system_root_dir.rb +1 -0
- data/lib/chef/chef_fs/file_system/repository/acl.rb +38 -0
- data/lib/chef/chef_fs/file_system/repository/{chef_repository_file_system_acls_dir.rb → acls_dir.rb} +14 -5
- data/lib/chef/chef_fs/file_system/repository/acls_sub_dir.rb +42 -0
- data/lib/chef/chef_fs/file_system/repository/base_file.rb +120 -0
- data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_entry.rb +1 -1
- data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb +36 -32
- data/lib/chef/chef_fs/file_system/repository/client.rb +38 -0
- data/lib/chef/chef_fs/file_system/repository/client_key.rb +38 -0
- data/lib/chef/chef_fs/file_system/repository/{chef_repository_file_system_client_keys_dir.rb → client_keys_dir.rb} +9 -5
- data/lib/chef/chef_fs/file_system/repository/client_keys_sub_dir.rb +42 -0
- data/lib/chef/chef_fs/file_system/repository/clients_dir.rb +40 -0
- data/lib/chef/chef_fs/file_system/repository/container.rb +38 -0
- data/lib/chef/chef_fs/file_system/repository/containers_dir.rb +41 -0
- data/lib/chef/chef_fs/file_system/repository/cookbooks_dir.rb +0 -1
- data/lib/chef/chef_fs/file_system/repository/data_bag_item.rb +3 -79
- data/lib/chef/chef_fs/file_system/repository/directory.rb +15 -2
- data/lib/chef/chef_fs/file_system/repository/environment.rb +38 -0
- data/lib/chef/chef_fs/file_system/repository/environments_dir.rb +41 -0
- data/lib/chef/chef_fs/file_system/repository/file_system_entry.rb +66 -30
- data/lib/chef/chef_fs/file_system/repository/group.rb +38 -0
- data/lib/chef/chef_fs/file_system/repository/groups_dir.rb +41 -0
- data/lib/chef/chef_fs/file_system/repository/node.rb +38 -0
- data/lib/chef/chef_fs/file_system/repository/nodes_dir.rb +41 -0
- data/lib/chef/chef_fs/file_system/repository/{chef_repository_file_system_policies_dir.rb → policies_dir.rb} +9 -5
- data/lib/chef/chef_fs/file_system/repository/policy.rb +38 -0
- data/lib/chef/chef_fs/file_system/repository/policy_group.rb +38 -0
- data/lib/chef/chef_fs/file_system/repository/policy_groups_dir.rb +41 -0
- data/lib/chef/chef_fs/file_system/repository/role.rb +38 -0
- data/lib/chef/chef_fs/file_system/repository/roles_dir.rb +41 -0
- data/lib/chef/chef_fs/file_system/repository/user.rb +38 -0
- data/lib/chef/chef_fs/file_system/repository/users_dir.rb +41 -0
- data/lib/chef/dsl/declare_resource.rb +182 -7
- data/lib/chef/http/json_input.rb +2 -2
- data/lib/chef/knife.rb +1 -1
- data/lib/chef/mixin/shell_out.rb +10 -21
- data/lib/chef/property.rb +9 -2
- data/lib/chef/provider.rb +8 -7
- data/lib/chef/provider/apt_repository.rb +8 -6
- data/lib/chef/provider/directory.rb +15 -1
- data/lib/chef/provider/env/windows.rb +1 -1
- data/lib/chef/provider/mdadm.rb +1 -0
- data/lib/chef/provider/package/easy_install.rb +2 -0
- data/lib/chef/provider/package/rubygems.rb +4 -1
- data/lib/chef/provider/package/windows.rb +1 -1
- data/lib/chef/recipe.rb +1 -2
- data/lib/chef/resource/apt_repository.rb +6 -6
- data/lib/chef/resource/mdadm.rb +9 -0
- data/lib/chef/resource_collection.rb +5 -0
- data/lib/chef/resource_collection/resource_list.rb +10 -0
- data/lib/chef/resource_collection/resource_set.rb +14 -11
- data/lib/chef/version.rb +1 -1
- data/spec/functional/resource/git_spec.rb +1 -3
- data/spec/functional/resource/group_spec.rb +5 -5
- data/spec/functional/tiny_server_spec.rb +1 -1
- data/spec/functional/util/powershell/cmdlet_spec.rb +1 -1
- data/spec/functional/win32/registry_spec.rb +3 -3
- data/spec/integration/solo/solo_spec.rb +2 -2
- data/spec/support/shared/functional/securable_resource.rb +1 -1
- data/spec/support/shared/unit/provider/file.rb +3 -3
- data/spec/support/shared/unit/windows_script_resource.rb +1 -1
- data/spec/unit/application/apply_spec.rb +1 -0
- data/spec/unit/chef_fs/file_system/repository/base_file_spec.rb +128 -0
- data/spec/unit/chef_fs/file_system/repository/directory_spec.rb +174 -0
- data/spec/unit/cookbook/metadata_spec.rb +1 -1
- data/spec/unit/dsl/declare_resource_spec.rb +335 -0
- data/spec/unit/knife/bootstrap_spec.rb +2 -2
- data/spec/unit/mixin/shell_out_spec.rb +4 -0
- data/spec/unit/node/attribute_spec.rb +1 -1
- data/spec/unit/node/immutable_collections_spec.rb +2 -2
- data/spec/unit/node_map_spec.rb +1 -1
- data/spec/unit/property/validation_spec.rb +23 -7
- data/spec/unit/provider/apt_repository_spec.rb +5 -0
- data/spec/unit/provider/apt_update_spec.rb +1 -0
- data/spec/unit/provider/directory_spec.rb +0 -7
- data/spec/unit/provider/file/content_spec.rb +1 -1
- data/spec/unit/provider/mdadm_spec.rb +9 -0
- data/spec/unit/provider/package/easy_install_spec.rb +6 -0
- data/spec/unit/provider/package/rubygems_spec.rb +8 -4
- data/spec/unit/provider/package/yum_spec.rb +1 -1
- data/spec/unit/provider/powershell_script_spec.rb +1 -1
- data/spec/unit/provider/user/dscl_spec.rb +6 -6
- data/spec/unit/recipe_spec.rb +1 -0
- data/spec/unit/resource/apt_repository_spec.rb +4 -0
- data/spec/unit/resource/file/verification_spec.rb +1 -1
- data/spec/unit/resource/file_spec.rb +2 -2
- data/spec/unit/resource/mdadm_spec.rb +7 -2
- data/spec/unit/resource_collection_spec.rb +30 -0
- data/spec/unit/resource_spec.rb +1 -1
- data/tasks/bin/bundle-platform +15 -0
- data/tasks/bin/bundle-platform.bat +2 -0
- data/tasks/bin/create-override-gemfile +110 -0
- data/tasks/bin/run_chef_tests +17 -0
- data/tasks/bin/run_external_test +47 -0
- data/tasks/bundle.rb +97 -0
- data/tasks/bundle_util.rb +94 -0
- data/tasks/changelog.rb +12 -0
- data/tasks/dependencies.rb +147 -0
- data/tasks/gemfile_util.rb +390 -0
- data/tasks/maintainers.rb +2 -1
- data/tasks/rspec.rb +2 -1
- metadata +61 -83
- data/acceptance/fips/test/integration/fips/serverspec/fips_spec.rb +0 -39
- data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_entry.rb +0 -83
- data/tasks/external_tests.rb +0 -64
@@ -105,7 +105,7 @@ describe Chef::Util::Powershell::Cmdlet, :windows_powershell_dsc_only do
|
|
105
105
|
context "when constructor is given invalid arguments" do
|
106
106
|
let(:cmd_output_format) { :invalid }
|
107
107
|
it "throws an exception if an invalid format is passed to the constructor" do
|
108
|
-
expect(lambda { simple_cmdlet }).to raise_error
|
108
|
+
expect(lambda { simple_cmdlet }).to raise_error(ArgumentError)
|
109
109
|
end
|
110
110
|
end
|
111
111
|
end
|
@@ -243,7 +243,7 @@ describe "Chef::Win32::Registry", :windows_only do
|
|
243
243
|
end
|
244
244
|
|
245
245
|
it "throws an exception when trying to cast an array to an int for a dword" do
|
246
|
-
expect { @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", { :name => "ShouldThrow", :type => :dword, :data => %w{one two} }) }.to raise_error
|
246
|
+
expect { @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", { :name => "ShouldThrow", :type => :dword, :data => %w{one two} }) }.to raise_error NoMethodError
|
247
247
|
end
|
248
248
|
|
249
249
|
# we are validating that the data gets .to_s called on it when type is a :string
|
@@ -261,11 +261,11 @@ describe "Chef::Win32::Registry", :windows_only do
|
|
261
261
|
# we are validating that the data gets .to_a called on it when type is a :multi_string
|
262
262
|
|
263
263
|
it "throws an exception when a multi-string is passed a number" do
|
264
|
-
expect { @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", { :name => "ShouldThrow", :type => :multi_string, :data => 65535 }) }.to raise_error
|
264
|
+
expect { @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", { :name => "ShouldThrow", :type => :multi_string, :data => 65535 }) }.to raise_error NoMethodError
|
265
265
|
end
|
266
266
|
|
267
267
|
it "throws an exception when a multi-string is passed a string" do
|
268
|
-
expect { @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", { :name => "ShouldBeWat", :type => :multi_string, :data => "foo" }) }.to raise_error
|
268
|
+
expect { @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", { :name => "ShouldBeWat", :type => :multi_string, :data => "foo" }) }.to raise_error NoMethodError
|
269
269
|
end
|
270
270
|
end
|
271
271
|
|
@@ -112,7 +112,7 @@ EOM
|
|
112
112
|
file "cookbooks/x/recipes/default.rb", <<EOM
|
113
113
|
ruby_block "sleeping" do
|
114
114
|
block do
|
115
|
-
sleep
|
115
|
+
sleep 10
|
116
116
|
end
|
117
117
|
end
|
118
118
|
EOM
|
@@ -134,7 +134,7 @@ EOM
|
|
134
134
|
-l debug -L #{path_to('logs/runs.log')}", :chdir => chef_dir)
|
135
135
|
|
136
136
|
# Give it some time to progress
|
137
|
-
sleep
|
137
|
+
sleep 5
|
138
138
|
|
139
139
|
# Instantiate the second chef-solo run
|
140
140
|
s2 = Process.spawn("#{chef_solo} -c \"#{path_to('config/solo.rb')}\" -o 'x::default' \
|
@@ -309,7 +309,7 @@ shared_examples_for "a securable resource without existing target" do
|
|
309
309
|
end
|
310
310
|
|
311
311
|
it "fails to set owner when owner has invalid characters" do
|
312
|
-
expect { resource.owner 'Lance "The Nose" Glindenberry III' }.to raise_error
|
312
|
+
expect { resource.owner 'Lance "The Nose" Glindenberry III' }.to raise_error(Chef::Exceptions::ValidationFailed)
|
313
313
|
end
|
314
314
|
|
315
315
|
it "sets owner when owner is specified with a \\" do
|
@@ -586,14 +586,14 @@ shared_examples_for Chef::Provider::File do
|
|
586
586
|
it "raises an exception when the content object returns a tempfile with a nil path" do
|
587
587
|
tempfile = double("Tempfile", :path => nil)
|
588
588
|
expect(provider.send(:content)).to receive(:tempfile).at_least(:once).and_return(tempfile)
|
589
|
-
expect { provider.send(:do_contents_changes) }.to raise_error
|
589
|
+
expect { provider.send(:do_contents_changes) }.to raise_error(RuntimeError)
|
590
590
|
end
|
591
591
|
|
592
592
|
it "raises an exception when the content object returns a tempfile that does not exist" do
|
593
593
|
tempfile = double("Tempfile", :path => "/tmp/foo-bar-baz")
|
594
594
|
expect(provider.send(:content)).to receive(:tempfile).at_least(:once).and_return(tempfile)
|
595
595
|
expect(File).to receive(:exists?).with("/tmp/foo-bar-baz").and_return(false)
|
596
|
-
expect { provider.send(:do_contents_changes) }.to raise_error
|
596
|
+
expect { provider.send(:do_contents_changes) }.to raise_error(RuntimeError)
|
597
597
|
end
|
598
598
|
end
|
599
599
|
|
@@ -712,7 +712,7 @@ shared_examples_for Chef::Provider::File do
|
|
712
712
|
it "should not try to backup or delete the file, and should not be updated by last action" do
|
713
713
|
expect(provider).not_to receive(:do_backup)
|
714
714
|
expect(File).not_to receive(:delete)
|
715
|
-
expect { provider.run_action(:delete) }.to raise_error()
|
715
|
+
expect { provider.run_action(:delete) }.to raise_error(Chef::Exceptions::InsufficientPermissions)
|
716
716
|
expect(resource).not_to be_updated_by_last_action
|
717
717
|
end
|
718
718
|
end
|
@@ -64,7 +64,7 @@ shared_examples_for "a Windows script resource" do
|
|
64
64
|
it "should raise an exception if the guard_interpreter is overridden from its default value" do
|
65
65
|
@resource.guard_interpreter :bash
|
66
66
|
@resource.only_if { true }
|
67
|
-
expect { @resource.should_skip?(:run) }.to raise_error
|
67
|
+
expect { @resource.should_skip?(:run) }.to raise_error(ArgumentError)
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
@@ -22,6 +22,7 @@ describe Chef::Application::Apply do
|
|
22
22
|
before do
|
23
23
|
@app = Chef::Application::Apply.new
|
24
24
|
allow(@app).to receive(:configure_logging).and_return(true)
|
25
|
+
allow(Chef::Log).to receive(:debug).with("FIPS mode is enabled.")
|
25
26
|
@recipe_text = "package 'nyancat'"
|
26
27
|
Chef::Config[:solo] = true
|
27
28
|
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright 2012-2016, Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require "spec_helper"
|
19
|
+
require "chef/chef_fs/file_system/repository/base_file"
|
20
|
+
require "chef/chef_fs/file_system/repository/directory"
|
21
|
+
require "chef/chef_fs/file_system/base_fs_object"
|
22
|
+
require "chef/chef_fs/file_system/exceptions"
|
23
|
+
require "chef/chef_fs/file_system/nonexistent_fs_object"
|
24
|
+
|
25
|
+
describe Chef::ChefFS::FileSystem::Repository::BaseFile do
|
26
|
+
let(:root) do
|
27
|
+
Chef::ChefFS::FileSystem::BaseFSDir.new("", nil)
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:tmp_dir) { Dir.mktmpdir }
|
31
|
+
|
32
|
+
let(:parent) do
|
33
|
+
Chef::ChefFS::FileSystem::Repository::Directory.new("test", root, tmp_dir)
|
34
|
+
end
|
35
|
+
|
36
|
+
let(:file) do
|
37
|
+
file = described_class.new("test_file.json", parent)
|
38
|
+
file.write_pretty_json = false
|
39
|
+
file
|
40
|
+
end
|
41
|
+
|
42
|
+
let(:content) { '"name": "canteloup"' }
|
43
|
+
let(:file_path) { File.join(tmp_dir, "test_file.json") }
|
44
|
+
|
45
|
+
after do
|
46
|
+
FileUtils.rm_f(file_path)
|
47
|
+
end
|
48
|
+
|
49
|
+
context "#is_json_file?" do
|
50
|
+
it "returns false when the file is not json" do
|
51
|
+
file = described_class.new("test_file.dpkg", parent)
|
52
|
+
expect(file.is_json_file?).to be_falsey
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns true when the file is json" do
|
56
|
+
expect(file.is_json_file?).to be_truthy
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "#name_valid?" do
|
61
|
+
it "rejects dotfiles" do
|
62
|
+
file = described_class.new(".test_file.json", parent)
|
63
|
+
expect(file.name_valid?).to be_falsey
|
64
|
+
end
|
65
|
+
|
66
|
+
it "rejects non json files" do
|
67
|
+
file = described_class.new("test_file.dpkg", parent)
|
68
|
+
expect(file.name_valid?).to be_falsey
|
69
|
+
end
|
70
|
+
|
71
|
+
it "allows correctly named files" do
|
72
|
+
expect(file.name_valid?).to be_truthy
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "#fs_entry_valid?" do
|
77
|
+
it "rejects invalid names" do
|
78
|
+
file = described_class.new("test_file.dpkg", parent)
|
79
|
+
expect(file.fs_entry_valid?).to be_falsey
|
80
|
+
end
|
81
|
+
|
82
|
+
it "rejects missing files" do
|
83
|
+
FileUtils.rm_f(file_path)
|
84
|
+
expect(file.fs_entry_valid?).to be_falsey
|
85
|
+
end
|
86
|
+
|
87
|
+
it "allows present and properly named files" do
|
88
|
+
FileUtils.touch(file_path)
|
89
|
+
expect(file.fs_entry_valid?).to be_truthy
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "#create" do
|
94
|
+
it "doesn't create an existing file" do
|
95
|
+
FileUtils.touch(file_path)
|
96
|
+
expect { file.create('"name": "canteloup"') }.to raise_error(Chef::ChefFS::FileSystem::AlreadyExistsError)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "creates a new file" do
|
100
|
+
expect(file).to receive(:write).with(content)
|
101
|
+
expect { file.create(content) }.to_not raise_error
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
context "#write" do
|
107
|
+
context "minimises a json object" do
|
108
|
+
it "not if pretty json is off" do
|
109
|
+
expect(file).to_not receive(:minimize)
|
110
|
+
file.write(content)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "not if it's not a json file" do
|
114
|
+
file = described_class.new("test_file.dpkg", parent)
|
115
|
+
file.write_pretty_json = true
|
116
|
+
expect(file).to_not receive(:minimize)
|
117
|
+
file.write(content)
|
118
|
+
end
|
119
|
+
|
120
|
+
it "correctly" do
|
121
|
+
file = described_class.new("test_file.json", parent)
|
122
|
+
file.write_pretty_json = true
|
123
|
+
expect(file).to receive(:minimize).with(content, file).and_return(content)
|
124
|
+
file.write(content)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Thom May (<thom@chef.io>)
|
3
|
+
# Copyright:: Copyright 2012-2016, Chef Software 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 "chef/chef_fs/file_system/repository/directory"
|
21
|
+
require "chef/chef_fs/file_system/base_fs_object"
|
22
|
+
require "chef/chef_fs/file_system/exceptions"
|
23
|
+
require "chef/chef_fs/file_system/nonexistent_fs_object"
|
24
|
+
|
25
|
+
CHILD_FILES = %w{ test1.json test2.json skip test3.json skip2 test4 }
|
26
|
+
|
27
|
+
class TestDirectory < Chef::ChefFS::FileSystem::Repository::Directory
|
28
|
+
def make_child_entry(name)
|
29
|
+
TestFile.new(name, self)
|
30
|
+
end
|
31
|
+
|
32
|
+
def can_have_child?(name, is_dir)
|
33
|
+
!is_dir && File.extname(name) == ".json"
|
34
|
+
end
|
35
|
+
|
36
|
+
def dir_ls
|
37
|
+
CHILD_FILES
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class TestFile < Chef::ChefFS::FileSystem::BaseFSObject
|
42
|
+
def fs_entry_valid?
|
43
|
+
name.start_with? "test"
|
44
|
+
end
|
45
|
+
|
46
|
+
def name_valid?
|
47
|
+
true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe Chef::ChefFS::FileSystem::Repository::Directory do
|
52
|
+
let(:root) do
|
53
|
+
Chef::ChefFS::FileSystem::BaseFSDir.new("", nil)
|
54
|
+
end
|
55
|
+
|
56
|
+
let(:tmp_dir) { Dir.mktmpdir }
|
57
|
+
|
58
|
+
let(:directory) do
|
59
|
+
described_class.new("test", root, tmp_dir)
|
60
|
+
end
|
61
|
+
|
62
|
+
let(:test_directory) do
|
63
|
+
TestDirectory.new("test", root, tmp_dir)
|
64
|
+
end
|
65
|
+
|
66
|
+
let(:file_double) do
|
67
|
+
double(TestFile, create: true, exists?: false)
|
68
|
+
end
|
69
|
+
|
70
|
+
context "#make_child_entry" do
|
71
|
+
it "raises if not implemented" do
|
72
|
+
expect { directory.send(:make_child_entry, "test") }.to raise_error("Not Implemented")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "#create_child" do
|
77
|
+
it "creates a new TestFile" do
|
78
|
+
expect(TestFile).to receive(:new).with("test_child", test_directory).and_return(file_double)
|
79
|
+
expect(file_double).to receive(:write).with("test")
|
80
|
+
test_directory.create_child("test_child", "test")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "#child" do
|
85
|
+
it "returns a child if it's valid" do
|
86
|
+
expect(test_directory.child("test")).to be_an_instance_of(TestFile)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "returns a non existent object otherwise" do
|
90
|
+
file_double = instance_double(TestFile, :name_valid? => false)
|
91
|
+
expect(TestFile).to receive(:new).with("test_child", test_directory).and_return(file_double)
|
92
|
+
expect(test_directory.child("test_child")).to be_an_instance_of(Chef::ChefFS::FileSystem::NonexistentFSObject)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "#children" do
|
97
|
+
before do
|
98
|
+
CHILD_FILES.sort.each do |child|
|
99
|
+
expect(TestFile).to receive(:new).with(child, test_directory).and_call_original
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it "creates a child for each name" do
|
104
|
+
test_directory.children
|
105
|
+
end
|
106
|
+
|
107
|
+
it "filters invalid names" do
|
108
|
+
expect(test_directory.children.map { |c| c.name }).to eql %w{ test1.json test2.json test3.json }
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "#empty?" do
|
113
|
+
it "is true if there are no children" do
|
114
|
+
expect(test_directory).to receive(:children).and_return([])
|
115
|
+
expect(test_directory.empty?).to be_truthy
|
116
|
+
end
|
117
|
+
|
118
|
+
it "is false if there are children" do
|
119
|
+
expect(test_directory.empty?).to be_falsey
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "checks entry validity" do
|
124
|
+
it "rejects dotfiles" do
|
125
|
+
dir = described_class.new(".test", root, tmp_dir)
|
126
|
+
expect(dir.name_valid?).to be_falsey
|
127
|
+
end
|
128
|
+
|
129
|
+
it "rejects files" do
|
130
|
+
Tempfile.open("test") do |file|
|
131
|
+
dir = described_class.new("test", root, file.path)
|
132
|
+
expect(dir.name_valid?).to be_truthy
|
133
|
+
expect(dir.fs_entry_valid?).to be_falsey
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
it "accepts directories" do
|
138
|
+
expect(directory.name_valid?).to be_truthy
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "creates directories" do
|
143
|
+
it "doesn't create an existing directory" do
|
144
|
+
expect { directory.create }.to raise_error(Chef::ChefFS::FileSystem::AlreadyExistsError)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "creates a new directory" do
|
148
|
+
FileUtils.rmdir(tmp_dir)
|
149
|
+
expect(Dir).to receive(:mkdir).with(tmp_dir)
|
150
|
+
expect { directory.create }.to_not raise_error
|
151
|
+
end
|
152
|
+
|
153
|
+
after do
|
154
|
+
FileUtils.rmdir(tmp_dir)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "deletes directories" do
|
159
|
+
it "won't delete a non-existant directory" do
|
160
|
+
FileUtils.rmdir(tmp_dir)
|
161
|
+
expect { directory.delete(true) }.to raise_error(Chef::ChefFS::FileSystem::NotFoundError)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "must delete recursively" do
|
165
|
+
expect { directory.delete(false) }.to raise_error(Chef::ChefFS::FileSystem::MustDeleteRecursivelyError)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "deletes a directory" do
|
169
|
+
expect(FileUtils).to receive(:rm_r).with(tmp_dir)
|
170
|
+
expect { directory.delete(true) }.to_not raise_error
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
@@ -707,7 +707,7 @@ describe Chef::Cookbook::Metadata do
|
|
707
707
|
}
|
708
708
|
expect {
|
709
709
|
metadata.attribute("test_cookbook/test", options)
|
710
|
-
}.to raise_error
|
710
|
+
}.to raise_error(Chef::Exceptions::ValidationFailed)
|
711
711
|
end
|
712
712
|
|
713
713
|
it "should error if default used with calculated" do
|
@@ -0,0 +1,335 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright 2008-2016, Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require "spec_helper"
|
19
|
+
|
20
|
+
describe Chef::ResourceCollection do
|
21
|
+
let(:run_context) do
|
22
|
+
cookbook_repo = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "data", "cookbooks"))
|
23
|
+
cookbook_loader = Chef::CookbookLoader.new(cookbook_repo)
|
24
|
+
cookbook_loader.load_cookbooks
|
25
|
+
node = Chef::Node.new
|
26
|
+
cookbook_collection = Chef::CookbookCollection.new(cookbook_loader)
|
27
|
+
events = Chef::EventDispatch::Dispatcher.new
|
28
|
+
Chef::RunContext.new(node, cookbook_collection, events)
|
29
|
+
end
|
30
|
+
|
31
|
+
let(:recipe) do
|
32
|
+
Chef::Recipe.new("hjk", "test", run_context)
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#declare_resource" do
|
36
|
+
before do
|
37
|
+
recipe.declare_resource(:zen_master, "monkey") do
|
38
|
+
something true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it "inserts into the resource collection" do
|
43
|
+
expect(run_context.resource_collection.first.to_s).to eql("zen_master[monkey]")
|
44
|
+
end
|
45
|
+
|
46
|
+
it "sets the property from the block" do
|
47
|
+
expect(run_context.resource_collection.first.something).to be true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#edit_resource!" do
|
52
|
+
it "raises if nothing is found" do
|
53
|
+
expect {
|
54
|
+
recipe.edit_resource!(:zen_master, "monkey") do
|
55
|
+
something true
|
56
|
+
end
|
57
|
+
}.to raise_error(Chef::Exceptions::ResourceNotFound)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "raises if nothing is found and no block is given" do
|
61
|
+
expect {
|
62
|
+
recipe.edit_resource!(:zen_master, "monkey")
|
63
|
+
}.to raise_error(Chef::Exceptions::ResourceNotFound)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "edits the resource if it finds one" do
|
67
|
+
resource = recipe.declare_resource(:zen_master, "monkey") do
|
68
|
+
something false
|
69
|
+
end
|
70
|
+
expect(
|
71
|
+
recipe.edit_resource!(:zen_master, "monkey") do
|
72
|
+
something true
|
73
|
+
end
|
74
|
+
).to eql(resource)
|
75
|
+
expect(run_context.resource_collection.all_resources.size).to eql(1)
|
76
|
+
expect(run_context.resource_collection.first.something).to be true
|
77
|
+
end
|
78
|
+
|
79
|
+
it "acts like find_resource! if not given a block and the resource exists" do
|
80
|
+
resource = recipe.declare_resource(:zen_master, "monkey") do
|
81
|
+
something false
|
82
|
+
end
|
83
|
+
expect(
|
84
|
+
recipe.edit_resource!(:zen_master, "monkey")
|
85
|
+
).to eql(resource)
|
86
|
+
expect(run_context.resource_collection.all_resources.size).to eql(1)
|
87
|
+
expect(run_context.resource_collection.first.something).to be false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "#edit_resource" do
|
92
|
+
it "inserts a resource if nothing is found" do
|
93
|
+
resource = recipe.edit_resource(:zen_master, "monkey") do
|
94
|
+
something true
|
95
|
+
end
|
96
|
+
expect(run_context.resource_collection.all_resources.size).to eql(1)
|
97
|
+
expect(run_context.resource_collection.first).to eql(resource)
|
98
|
+
expect(run_context.resource_collection.first.something).to be true
|
99
|
+
end
|
100
|
+
|
101
|
+
it "inserts a resource even if not given a block" do
|
102
|
+
resource = recipe.edit_resource(:zen_master, "monkey")
|
103
|
+
expect(run_context.resource_collection.all_resources.size).to eql(1)
|
104
|
+
expect(run_context.resource_collection.first).to eql(resource)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "edits the resource if it finds one" do
|
108
|
+
resource = recipe.declare_resource(:zen_master, "monkey") do
|
109
|
+
something false
|
110
|
+
end
|
111
|
+
expect(
|
112
|
+
recipe.edit_resource(:zen_master, "monkey") do
|
113
|
+
something true
|
114
|
+
end
|
115
|
+
).to eql(resource)
|
116
|
+
expect(run_context.resource_collection.all_resources.size).to eql(1)
|
117
|
+
expect(run_context.resource_collection.first.something).to be true
|
118
|
+
end
|
119
|
+
|
120
|
+
it "acts like find_resource if not given a block and the resource exists" do
|
121
|
+
resource = recipe.declare_resource(:zen_master, "monkey") do
|
122
|
+
something false
|
123
|
+
end
|
124
|
+
expect(
|
125
|
+
recipe.edit_resource(:zen_master, "monkey")
|
126
|
+
).to eql(resource)
|
127
|
+
expect(run_context.resource_collection.all_resources.size).to eql(1)
|
128
|
+
expect(run_context.resource_collection.first.something).to be false
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "#find_resource!" do
|
133
|
+
it "raises if nothing is found" do
|
134
|
+
expect {
|
135
|
+
recipe.find_resource!(:zen_master, "monkey")
|
136
|
+
}.to raise_error(Chef::Exceptions::ResourceNotFound)
|
137
|
+
end
|
138
|
+
|
139
|
+
it "raises if given a block" do
|
140
|
+
resource = recipe.declare_resource(:zen_master, "monkey") do
|
141
|
+
something false
|
142
|
+
end
|
143
|
+
expect {
|
144
|
+
recipe.find_resource!(:zen_master, "monkey") do
|
145
|
+
something false
|
146
|
+
end
|
147
|
+
}.to raise_error(ArgumentError)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "returns the resource if it finds one" do
|
151
|
+
resource = recipe.declare_resource(:zen_master, "monkey") do
|
152
|
+
something false
|
153
|
+
end
|
154
|
+
expect(
|
155
|
+
recipe.find_resource!(:zen_master, "monkey")
|
156
|
+
).to eql(resource)
|
157
|
+
expect(run_context.resource_collection.all_resources.size).to eql(1)
|
158
|
+
expect(run_context.resource_collection.first.something).to be false
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "#find_resource without block" do
|
163
|
+
it "returns nil if nothing is found" do
|
164
|
+
expect(recipe.find_resource(:zen_master, "monkey")).to be nil
|
165
|
+
expect(run_context.resource_collection.all_resources.size).to eql(0)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "returns the resource if it finds one" do
|
169
|
+
resource = recipe.declare_resource(:zen_master, "monkey") do
|
170
|
+
something false
|
171
|
+
end
|
172
|
+
expect(
|
173
|
+
recipe.find_resource(:zen_master, "monkey")
|
174
|
+
).to eql(resource)
|
175
|
+
expect(run_context.resource_collection.all_resources.size).to eql(1)
|
176
|
+
expect(run_context.resource_collection.first.something).to be false
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe "#find_resource with block" do
|
181
|
+
it "inserts a resource if nothing is found" do
|
182
|
+
resource = recipe.find_resource(:zen_master, "monkey") do
|
183
|
+
something true
|
184
|
+
end
|
185
|
+
expect(run_context.resource_collection.all_resources.size).to eql(1)
|
186
|
+
expect(run_context.resource_collection.first).to eql(resource)
|
187
|
+
expect(run_context.resource_collection.first.something).to be true
|
188
|
+
end
|
189
|
+
|
190
|
+
it "returns the resource if it finds one" do
|
191
|
+
resource = recipe.declare_resource(:zen_master, "monkey") do
|
192
|
+
something false
|
193
|
+
end
|
194
|
+
expect(
|
195
|
+
recipe.find_resource(:zen_master, "monkey") do
|
196
|
+
something true
|
197
|
+
end
|
198
|
+
).to eql(resource)
|
199
|
+
expect(run_context.resource_collection.all_resources.size).to eql(1)
|
200
|
+
expect(run_context.resource_collection.first.something).to be false
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe "#delete_resource" do
|
205
|
+
it "returns nil if nothing is found" do
|
206
|
+
expect(
|
207
|
+
recipe.delete_resource(:zen_master, "monkey")
|
208
|
+
).to be nil
|
209
|
+
end
|
210
|
+
|
211
|
+
it "deletes and returns the resource if it finds one" do
|
212
|
+
resource = recipe.declare_resource(:zen_master, "monkey") do
|
213
|
+
something false
|
214
|
+
end
|
215
|
+
expect(
|
216
|
+
recipe.delete_resource(:zen_master, "monkey")
|
217
|
+
).to eql(resource)
|
218
|
+
expect(run_context.resource_collection.all_resources.size).to eql(0)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
describe "#delete_resource!" do
|
223
|
+
it "raises if nothing is found" do
|
224
|
+
expect {
|
225
|
+
recipe.delete_resource!(:zen_master, "monkey")
|
226
|
+
}.to raise_error(Chef::Exceptions::ResourceNotFound)
|
227
|
+
end
|
228
|
+
|
229
|
+
it "deletes and returns the resource if it finds one" do
|
230
|
+
resource = recipe.declare_resource(:zen_master, "monkey") do
|
231
|
+
something false
|
232
|
+
end
|
233
|
+
expect(
|
234
|
+
recipe.delete_resource!(:zen_master, "monkey")
|
235
|
+
).to eql(resource)
|
236
|
+
expect(run_context.resource_collection.all_resources.size).to eql(0)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
describe "run_context helpers" do
|
241
|
+
|
242
|
+
let(:parent_run_context) do
|
243
|
+
run_context.create_child
|
244
|
+
end
|
245
|
+
|
246
|
+
let(:child_run_context) do
|
247
|
+
parent_run_context.create_child
|
248
|
+
end
|
249
|
+
|
250
|
+
let(:parent_recipe) do
|
251
|
+
Chef::Recipe.new("hjk", "parent", parent_run_context)
|
252
|
+
end
|
253
|
+
|
254
|
+
let(:child_recipe) do
|
255
|
+
Chef::Recipe.new("hjk", "child", child_run_context)
|
256
|
+
end
|
257
|
+
|
258
|
+
before do
|
259
|
+
# wire up our outer run context to the root Chef.run_context
|
260
|
+
allow(Chef).to receive(:run_context).and_return(run_context)
|
261
|
+
end
|
262
|
+
|
263
|
+
it "our tests have correct separation" do
|
264
|
+
child_resource = child_recipe.declare_resource(:zen_master, "child") do
|
265
|
+
something false
|
266
|
+
end
|
267
|
+
parent_resource = parent_recipe.declare_resource(:zen_master, "parent") do
|
268
|
+
something false
|
269
|
+
end
|
270
|
+
root_resource = recipe.declare_resource(:zen_master, "root") do
|
271
|
+
something false
|
272
|
+
end
|
273
|
+
expect(run_context.resource_collection.first).to eql(root_resource)
|
274
|
+
expect(run_context.resource_collection.first.to_s).to eql("zen_master[root]")
|
275
|
+
expect(run_context.resource_collection.all_resources.size).to eql(1)
|
276
|
+
expect(parent_run_context.resource_collection.first).to eql(parent_resource)
|
277
|
+
expect(parent_run_context.resource_collection.first.to_s).to eql("zen_master[parent]")
|
278
|
+
expect(parent_run_context.resource_collection.all_resources.size).to eql(1)
|
279
|
+
expect(child_run_context.resource_collection.first).to eql(child_resource)
|
280
|
+
expect(child_run_context.resource_collection.first.to_s).to eql("zen_master[child]")
|
281
|
+
expect(child_run_context.resource_collection.all_resources.size).to eql(1)
|
282
|
+
end
|
283
|
+
|
284
|
+
it "with_run_context with :parent lets us build resources in the parent run_context from the child" do
|
285
|
+
child_recipe.instance_eval do
|
286
|
+
with_run_context(:parent) do
|
287
|
+
declare_resource(:zen_master, "parent") do
|
288
|
+
something false
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
expect(run_context.resource_collection.all_resources.size).to eql(0)
|
293
|
+
expect(parent_run_context.resource_collection.all_resources.size).to eql(1)
|
294
|
+
expect(parent_run_context.resource_collection.first.to_s).to eql("zen_master[parent]")
|
295
|
+
expect(child_run_context.resource_collection.all_resources.size).to eql(0)
|
296
|
+
end
|
297
|
+
|
298
|
+
it "with_run_context with :root lets us build resources in the root run_context from the child" do
|
299
|
+
child_recipe.instance_eval do
|
300
|
+
with_run_context(:root) do
|
301
|
+
declare_resource(:zen_master, "root") do
|
302
|
+
something false
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
expect(run_context.resource_collection.first.to_s).to eql("zen_master[root]")
|
307
|
+
expect(run_context.resource_collection.all_resources.size).to eql(1)
|
308
|
+
expect(parent_run_context.resource_collection.all_resources.size).to eql(0)
|
309
|
+
expect(child_run_context.resource_collection.all_resources.size).to eql(0)
|
310
|
+
end
|
311
|
+
|
312
|
+
it "with_run_context also takes a RunContext object as an argument" do
|
313
|
+
child_recipe.instance_exec(parent_run_context) do |parent_run_context|
|
314
|
+
with_run_context(parent_run_context) do
|
315
|
+
declare_resource(:zen_master, "parent") do
|
316
|
+
something false
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
expect(run_context.resource_collection.all_resources.size).to eql(0)
|
321
|
+
expect(parent_run_context.resource_collection.all_resources.size).to eql(1)
|
322
|
+
expect(parent_run_context.resource_collection.first.to_s).to eql("zen_master[parent]")
|
323
|
+
expect(child_run_context.resource_collection.all_resources.size).to eql(0)
|
324
|
+
end
|
325
|
+
|
326
|
+
it "with_run_context returns the return value of the block" do
|
327
|
+
child_recipe.instance_eval do
|
328
|
+
ret = with_run_context(:root) do
|
329
|
+
"return value"
|
330
|
+
end
|
331
|
+
raise "failed" unless ret == "return value"
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|