chef 12.9.41-universal-mingw32 → 12.10.24-universal-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.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +52 -13
  3. data/README.md +145 -0
  4. data/Rakefile +4 -14
  5. data/VERSION +1 -1
  6. data/acceptance/.gitignore +0 -1
  7. data/acceptance/Gemfile +2 -2
  8. data/acceptance/Gemfile.lock +235 -0
  9. data/acceptance/fips/.kitchen.yml +5 -1
  10. data/acceptance/fips/test/integration/{fips → fips-integration}/serverspec/Gemfile +0 -0
  11. data/acceptance/fips/test/integration/fips-integration/serverspec/fips-integration_spec.rb +51 -0
  12. data/acceptance/fips/test/integration/fips-unit-functional/serverspec/Gemfile +3 -0
  13. data/acceptance/fips/test/integration/fips-unit-functional/serverspec/fips-unit-functional_spec.rb +56 -0
  14. data/{chef-windows.gemspec → chef-universal-mingw32.gemspec} +0 -0
  15. data/chef.gemspec +0 -6
  16. data/{lib → lib-backcompat}/chef/chef_fs/file_system/already_exists_error.rb +0 -0
  17. data/{lib → lib-backcompat}/chef/chef_fs/file_system/cookbook_frozen_error.rb +0 -0
  18. data/{lib → lib-backcompat}/chef/chef_fs/file_system/default_environment_cannot_be_modified_error.rb +0 -0
  19. data/{lib → lib-backcompat}/chef/chef_fs/file_system/file_system_error.rb +0 -0
  20. data/{lib → lib-backcompat}/chef/chef_fs/file_system/must_delete_recursively_error.rb +0 -0
  21. data/{lib → lib-backcompat}/chef/chef_fs/file_system/not_found_error.rb +0 -0
  22. data/{lib → lib-backcompat}/chef/chef_fs/file_system/operation_failed_error.rb +0 -0
  23. data/{lib → lib-backcompat}/chef/chef_fs/file_system/operation_not_allowed_error.rb +0 -0
  24. data/lib-backcompat/chef/chef_fs/file_system/repository/chef_repository_file_system_acls_dir.rb +5 -0
  25. data/lib-backcompat/chef/chef_fs/file_system/repository/chef_repository_file_system_client_keys_dir.rb +5 -0
  26. data/lib-backcompat/chef/chef_fs/file_system/repository/chef_repository_file_system_entry.rb +6 -0
  27. data/lib-backcompat/chef/chef_fs/file_system/repository/chef_repository_file_system_policies_dir.rb +5 -0
  28. data/{lib → lib-backcompat}/chef/chef_fs/file_system/repository/file_system_root_dir.rb +1 -0
  29. data/lib/chef/chef_fs/file_system/repository/acl.rb +38 -0
  30. data/lib/chef/chef_fs/file_system/repository/{chef_repository_file_system_acls_dir.rb → acls_dir.rb} +14 -5
  31. data/lib/chef/chef_fs/file_system/repository/acls_sub_dir.rb +42 -0
  32. data/lib/chef/chef_fs/file_system/repository/base_file.rb +120 -0
  33. data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_entry.rb +1 -1
  34. data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb +36 -32
  35. data/lib/chef/chef_fs/file_system/repository/client.rb +38 -0
  36. data/lib/chef/chef_fs/file_system/repository/client_key.rb +38 -0
  37. data/lib/chef/chef_fs/file_system/repository/{chef_repository_file_system_client_keys_dir.rb → client_keys_dir.rb} +9 -5
  38. data/lib/chef/chef_fs/file_system/repository/client_keys_sub_dir.rb +42 -0
  39. data/lib/chef/chef_fs/file_system/repository/clients_dir.rb +40 -0
  40. data/lib/chef/chef_fs/file_system/repository/container.rb +38 -0
  41. data/lib/chef/chef_fs/file_system/repository/containers_dir.rb +41 -0
  42. data/lib/chef/chef_fs/file_system/repository/cookbooks_dir.rb +0 -1
  43. data/lib/chef/chef_fs/file_system/repository/data_bag_item.rb +3 -79
  44. data/lib/chef/chef_fs/file_system/repository/directory.rb +15 -2
  45. data/lib/chef/chef_fs/file_system/repository/environment.rb +38 -0
  46. data/lib/chef/chef_fs/file_system/repository/environments_dir.rb +41 -0
  47. data/lib/chef/chef_fs/file_system/repository/file_system_entry.rb +66 -30
  48. data/lib/chef/chef_fs/file_system/repository/group.rb +38 -0
  49. data/lib/chef/chef_fs/file_system/repository/groups_dir.rb +41 -0
  50. data/lib/chef/chef_fs/file_system/repository/node.rb +38 -0
  51. data/lib/chef/chef_fs/file_system/repository/nodes_dir.rb +41 -0
  52. data/lib/chef/chef_fs/file_system/repository/{chef_repository_file_system_policies_dir.rb → policies_dir.rb} +9 -5
  53. data/lib/chef/chef_fs/file_system/repository/policy.rb +38 -0
  54. data/lib/chef/chef_fs/file_system/repository/policy_group.rb +38 -0
  55. data/lib/chef/chef_fs/file_system/repository/policy_groups_dir.rb +41 -0
  56. data/lib/chef/chef_fs/file_system/repository/role.rb +38 -0
  57. data/lib/chef/chef_fs/file_system/repository/roles_dir.rb +41 -0
  58. data/lib/chef/chef_fs/file_system/repository/user.rb +38 -0
  59. data/lib/chef/chef_fs/file_system/repository/users_dir.rb +41 -0
  60. data/lib/chef/dsl/declare_resource.rb +182 -7
  61. data/lib/chef/http/json_input.rb +2 -2
  62. data/lib/chef/knife.rb +1 -1
  63. data/lib/chef/mixin/shell_out.rb +10 -21
  64. data/lib/chef/property.rb +9 -2
  65. data/lib/chef/provider.rb +8 -7
  66. data/lib/chef/provider/apt_repository.rb +8 -6
  67. data/lib/chef/provider/directory.rb +15 -1
  68. data/lib/chef/provider/env/windows.rb +1 -1
  69. data/lib/chef/provider/mdadm.rb +1 -0
  70. data/lib/chef/provider/package/easy_install.rb +2 -0
  71. data/lib/chef/provider/package/rubygems.rb +4 -1
  72. data/lib/chef/provider/package/windows.rb +1 -1
  73. data/lib/chef/recipe.rb +1 -2
  74. data/lib/chef/resource/apt_repository.rb +6 -6
  75. data/lib/chef/resource/mdadm.rb +9 -0
  76. data/lib/chef/resource_collection.rb +5 -0
  77. data/lib/chef/resource_collection/resource_list.rb +10 -0
  78. data/lib/chef/resource_collection/resource_set.rb +14 -11
  79. data/lib/chef/version.rb +1 -1
  80. data/spec/functional/resource/git_spec.rb +1 -3
  81. data/spec/functional/resource/group_spec.rb +5 -5
  82. data/spec/functional/tiny_server_spec.rb +1 -1
  83. data/spec/functional/util/powershell/cmdlet_spec.rb +1 -1
  84. data/spec/functional/win32/registry_spec.rb +3 -3
  85. data/spec/integration/solo/solo_spec.rb +2 -2
  86. data/spec/support/shared/functional/securable_resource.rb +1 -1
  87. data/spec/support/shared/unit/provider/file.rb +3 -3
  88. data/spec/support/shared/unit/windows_script_resource.rb +1 -1
  89. data/spec/unit/application/apply_spec.rb +1 -0
  90. data/spec/unit/chef_fs/file_system/repository/base_file_spec.rb +128 -0
  91. data/spec/unit/chef_fs/file_system/repository/directory_spec.rb +174 -0
  92. data/spec/unit/cookbook/metadata_spec.rb +1 -1
  93. data/spec/unit/dsl/declare_resource_spec.rb +335 -0
  94. data/spec/unit/knife/bootstrap_spec.rb +2 -2
  95. data/spec/unit/mixin/shell_out_spec.rb +4 -0
  96. data/spec/unit/node/attribute_spec.rb +1 -1
  97. data/spec/unit/node/immutable_collections_spec.rb +2 -2
  98. data/spec/unit/node_map_spec.rb +1 -1
  99. data/spec/unit/property/validation_spec.rb +23 -7
  100. data/spec/unit/provider/apt_repository_spec.rb +5 -0
  101. data/spec/unit/provider/apt_update_spec.rb +1 -0
  102. data/spec/unit/provider/directory_spec.rb +0 -7
  103. data/spec/unit/provider/file/content_spec.rb +1 -1
  104. data/spec/unit/provider/mdadm_spec.rb +9 -0
  105. data/spec/unit/provider/package/easy_install_spec.rb +6 -0
  106. data/spec/unit/provider/package/rubygems_spec.rb +8 -4
  107. data/spec/unit/provider/package/yum_spec.rb +1 -1
  108. data/spec/unit/provider/powershell_script_spec.rb +1 -1
  109. data/spec/unit/provider/user/dscl_spec.rb +6 -6
  110. data/spec/unit/recipe_spec.rb +1 -0
  111. data/spec/unit/resource/apt_repository_spec.rb +4 -0
  112. data/spec/unit/resource/file/verification_spec.rb +1 -1
  113. data/spec/unit/resource/file_spec.rb +2 -2
  114. data/spec/unit/resource/mdadm_spec.rb +7 -2
  115. data/spec/unit/resource_collection_spec.rb +30 -0
  116. data/spec/unit/resource_spec.rb +1 -1
  117. data/tasks/bin/bundle-platform +15 -0
  118. data/tasks/bin/bundle-platform.bat +2 -0
  119. data/tasks/bin/create-override-gemfile +110 -0
  120. data/tasks/bin/run_chef_tests +17 -0
  121. data/tasks/bin/run_external_test +47 -0
  122. data/tasks/bundle.rb +97 -0
  123. data/tasks/bundle_util.rb +94 -0
  124. data/tasks/changelog.rb +12 -0
  125. data/tasks/dependencies.rb +147 -0
  126. data/tasks/gemfile_util.rb +390 -0
  127. data/tasks/maintainers.rb +2 -1
  128. data/tasks/rspec.rb +2 -1
  129. metadata +61 -83
  130. data/acceptance/fips/test/integration/fips/serverspec/fips_spec.rb +0 -39
  131. data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_entry.rb +0 -83
  132. data/tasks/external_tests.rb +0 -64
@@ -26,7 +26,7 @@ describe TinyServer::API do
26
26
  end
27
27
 
28
28
  it "is a Singleton" do
29
- expect { TinyServer::API.new }.to raise_error
29
+ expect { TinyServer::API.new }.to raise_error NoMethodError
30
30
  end
31
31
 
32
32
  it "clears the router" do
@@ -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 5
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 1
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#(Chef::Exceptions::ValidationFailed)
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