microwave 1.0.4 → 11.400.2
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.
- data/CONTRIBUTING.md +155 -0
- data/README.md +89 -0
- data/Rakefile +2 -2
- data/bin/chef-apply +25 -0
- data/bin/chef-shell +34 -0
- data/bin/chef-solo +0 -2
- data/bin/shef +6 -5
- data/lib/chef.rb +2 -4
- data/spec/data/big_json.json +2 -1
- data/spec/data/big_json_plus_one.json +2 -1
- data/spec/data/cookbooks/chefignore +2 -0
- data/spec/data/cookbooks/openldap/attributes/default.rb +10 -9
- data/spec/data/cookbooks/openldap/attributes/smokey.rb +1 -1
- data/spec/data/git_bundles/sinatra-test-app-with-callback-files.gitbundle +0 -0
- data/spec/data/git_bundles/sinatra-test-app-with-symlinks.gitbundle +0 -0
- data/spec/data/git_bundles/sinatra-test-app.gitbundle +0 -0
- data/spec/data/lwrp/providers/inline_compiler.rb +26 -0
- data/spec/data/nodes/default.rb +3 -3
- data/spec/data/nodes/test.example.com.rb +3 -3
- data/spec/data/nodes/test.rb +3 -3
- data/spec/data/partial_one.erb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep1/attributes/default.rb +4 -0
- data/spec/data/run_context/cookbooks/circular-dep1/definitions/circular_dep1_res.rb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep1/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/circular-dep1/metadata.rb +2 -0
- data/spec/data/run_context/cookbooks/circular-dep1/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep1/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/circular-dep1/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep2/attributes/default.rb +3 -0
- data/spec/data/run_context/cookbooks/circular-dep2/definitions/circular_dep2_res.rb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep2/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/circular-dep2/metadata.rb +2 -0
- data/spec/data/run_context/cookbooks/circular-dep2/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep2/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/circular-dep2/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency1/attributes/aa_first.rb +2 -0
- data/spec/data/run_context/cookbooks/dependency1/attributes/default.rb +2 -0
- data/spec/data/run_context/cookbooks/dependency1/attributes/zz_last.rb +3 -0
- data/spec/data/run_context/cookbooks/dependency1/definitions/dependency1_res.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency1/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/dependency1/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency1/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/dependency1/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency2/attributes/default.rb +3 -0
- data/spec/data/run_context/cookbooks/dependency2/definitions/dependency2_res.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency2/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/dependency2/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency2/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/dependency2/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/no-default-attr/attributes/server.rb +3 -0
- data/spec/data/run_context/cookbooks/no-default-attr/definitions/no_default-attr_res.rb +1 -0
- data/spec/data/run_context/cookbooks/no-default-attr/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/no-default-attr/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/no-default-attr/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/attributes/default.rb +3 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/definitions/test_with-circular-deps_res.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/metadata.rb +2 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-deps/attributes/default.rb +3 -0
- data/spec/data/run_context/cookbooks/test-with-deps/definitions/test_with-deps_res.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-deps/libraries/lib.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-deps/metadata.rb +3 -0
- data/spec/data/run_context/cookbooks/test-with-deps/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-deps/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/test-with-deps/recipes/server.rb +0 -0
- data/spec/data/run_context/cookbooks/test-with-deps/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/test/attributes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/test/attributes/george.rb +1 -1
- data/spec/data/run_context/cookbooks/test/definitions/test_res.rb +1 -0
- data/spec/data/run_context/cookbooks/test/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/test/resources/resource.rb +1 -0
- data/spec/data/shef-config.rb +10 -0
- data/spec/functional/dsl/registry_helper_spec.rb +63 -0
- data/spec/functional/knife/cookbook_delete_spec.rb +0 -2
- data/spec/functional/knife/exec_spec.rb +4 -6
- data/spec/functional/knife/smoke_test.rb +34 -0
- data/spec/functional/knife/ssh_spec.rb +64 -3
- data/spec/functional/resource/cookbook_file_spec.rb +33 -2
- data/spec/functional/resource/deploy_revision_spec.rb +515 -0
- data/spec/functional/resource/directory_spec.rb +4 -0
- data/spec/functional/resource/file_spec.rb +56 -22
- data/spec/functional/resource/link_spec.rb +12 -10
- data/spec/functional/resource/registry_spec.rb +572 -0
- data/spec/functional/resource/remote_directory_spec.rb +142 -36
- data/spec/functional/resource/remote_file_spec.rb +28 -3
- data/spec/functional/resource/template_spec.rb +23 -2
- data/spec/functional/run_lock_spec.rb +238 -0
- data/spec/functional/shell_spec.rb +101 -0
- data/spec/functional/tiny_server_spec.rb +5 -4
- data/spec/functional/win32/registry_helper_spec.rb +632 -0
- data/spec/functional/win32/security_spec.rb +37 -0
- data/spec/spec_helper.rb +15 -3
- data/spec/stress/win32/security_spec.rb +5 -5
- data/spec/support/chef_helpers.rb +14 -3
- data/spec/support/lib/chef/resource/cat.rb +3 -5
- data/spec/support/lib/chef/resource/one_two_three_four.rb +8 -10
- data/spec/support/lib/chef/resource/zen_master.rb +8 -10
- data/spec/support/matchers/leak.rb +1 -1
- data/spec/support/platform_helpers.rb +18 -0
- data/spec/support/shared/functional/directory_resource.rb +85 -23
- data/spec/support/shared/functional/file_resource.rb +198 -53
- data/spec/support/shared/functional/securable_resource.rb +140 -105
- data/spec/support/shared/functional/securable_resource_with_reporting.rb +375 -0
- data/spec/support/shared/unit/file_system_support.rb +110 -0
- data/spec/support/shared/unit/platform_introspector.rb +162 -0
- data/spec/tiny_server.rb +29 -10
- data/spec/unit/api_client/registration_spec.rb +172 -0
- data/spec/unit/api_client_spec.rb +156 -103
- data/spec/unit/application/apply.rb +84 -0
- data/spec/unit/application/knife_spec.rb +5 -0
- data/spec/unit/application_spec.rb +57 -2
- data/spec/unit/chef_fs/diff_spec.rb +329 -0
- data/spec/unit/chef_fs/file_pattern_spec.rb +526 -0
- data/spec/unit/chef_fs/file_system/chef_server_root_dir_spec.rb +237 -0
- data/spec/unit/chef_fs/file_system/cookbooks_dir_spec.rb +568 -0
- data/spec/unit/chef_fs/file_system/data_bags_dir_spec.rb +220 -0
- data/spec/unit/chef_fs/file_system_spec.rb +136 -0
- data/spec/unit/client_spec.rb +188 -16
- data/spec/unit/config_spec.rb +54 -4
- data/spec/unit/cookbook/chefignore_spec.rb +2 -1
- data/spec/unit/cookbook/syntax_check_spec.rb +48 -109
- data/spec/unit/cookbook_loader_spec.rb +153 -91
- data/spec/unit/cookbook_manifest_spec.rb +81 -81
- data/spec/unit/cookbook_spec.rb +3 -20
- data/spec/unit/cookbook_version_spec.rb +23 -122
- data/spec/unit/digester_spec.rb +50 -0
- data/spec/unit/dsl/data_query_spec.rb +66 -0
- data/spec/unit/dsl/platform_introspection_spec.rb +130 -0
- data/spec/unit/dsl/regsitry_helper_spec.rb +55 -0
- data/spec/unit/encrypted_data_bag_item_spec.rb +126 -10
- data/spec/unit/environment_spec.rb +0 -130
- data/spec/unit/exceptions_spec.rb +2 -3
- data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +23 -3
- data/spec/unit/json_compat_spec.rb +69 -0
- data/spec/unit/knife/bootstrap_spec.rb +81 -28
- data/spec/unit/knife/client_reregister_spec.rb +23 -22
- data/spec/unit/knife/configure_spec.rb +29 -26
- data/spec/unit/knife/cookbook_metadata_spec.rb +11 -4
- data/spec/unit/knife/cookbook_site_install_spec.rb +12 -2
- data/spec/unit/knife/cookbook_test_spec.rb +1 -0
- data/spec/unit/knife/cookbook_upload_spec.rb +41 -2
- data/spec/unit/knife/core/bootstrap_context_spec.rb +8 -1
- data/spec/unit/knife/core/ui_spec.rb +156 -7
- data/spec/unit/knife/data_bag_create_spec.rb +14 -0
- data/spec/unit/knife/data_bag_edit_spec.rb +14 -4
- data/spec/unit/knife/data_bag_from_file_spec.rb +17 -5
- data/spec/unit/knife/data_bag_show_spec.rb +11 -4
- data/spec/unit/knife/index_rebuild_spec.rb +96 -33
- data/spec/unit/knife/knife_help.rb +7 -7
- data/spec/unit/knife/node_run_list_remove_spec.rb +2 -1
- data/spec/unit/knife/ssh_spec.rb +121 -15
- data/spec/unit/knife/status_spec.rb +2 -2
- data/spec/unit/knife/user_create_spec.rb +86 -0
- data/spec/unit/knife/user_delete_spec.rb +39 -0
- data/spec/unit/knife/user_edit_spec.rb +42 -0
- data/spec/unit/knife/user_list_spec.rb +32 -0
- data/spec/unit/knife/user_reregister_spec.rb +53 -0
- data/spec/unit/knife/user_show_spec.rb +41 -0
- data/spec/unit/knife_spec.rb +53 -0
- data/spec/unit/lwrp_spec.rb +59 -17
- data/spec/unit/mixin/checksum_spec.rb +2 -2
- data/spec/unit/mixin/deep_merge_spec.rb +56 -491
- data/spec/unit/mixin/deprecation_spec.rb +23 -0
- data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +6 -1
- data/spec/unit/mixin/params_validate_spec.rb +4 -2
- data/spec/unit/mixin/securable_spec.rb +5 -3
- data/spec/unit/mixin/template_spec.rb +119 -0
- data/spec/unit/node/attribute_spec.rb +272 -137
- data/spec/unit/node/immutable_collections_spec.rb +139 -0
- data/spec/unit/node_spec.rb +411 -339
- data/spec/unit/platform_spec.rb +8 -8
- data/spec/unit/provider/breakpoint_spec.rb +8 -8
- data/spec/unit/provider/cookbook_file_spec.rb +4 -8
- data/spec/unit/provider/deploy/revision_spec.rb +2 -8
- data/spec/unit/provider/deploy_spec.rb +6 -40
- data/spec/unit/provider/directory_spec.rb +103 -68
- data/spec/unit/provider/erl_call_spec.rb +0 -2
- data/spec/unit/provider/file_spec.rb +69 -59
- data/spec/unit/provider/git_spec.rb +0 -10
- data/spec/unit/provider/group/groupadd_spec.rb +1 -1
- data/spec/unit/provider/group/usermod_spec.rb +2 -2
- data/spec/unit/provider/http_request_spec.rb +28 -69
- data/spec/unit/provider/ifconfig_spec.rb +2 -2
- data/spec/unit/provider/link_spec.rb +1 -1
- data/spec/unit/provider/ohai_spec.rb +4 -4
- data/spec/unit/provider/package/apt_spec.rb +0 -1
- data/spec/unit/provider/package/ips_spec.rb +0 -1
- data/spec/unit/provider/package/rubygems_spec.rb +0 -18
- data/spec/unit/provider/package/yum_spec.rb +79 -15
- data/spec/unit/provider/package_spec.rb +7 -5
- data/spec/unit/provider/registry_key_spec.rb +269 -0
- data/spec/unit/provider/remote_directory_spec.rb +24 -7
- data/spec/unit/provider/remote_file_spec.rb +36 -0
- data/spec/unit/provider/route_spec.rb +3 -6
- data/spec/unit/provider/ruby_block_spec.rb +8 -0
- data/spec/unit/provider/service/arch_service_spec.rb +4 -4
- data/spec/unit/provider/service/debian_service_spec.rb +1 -1
- data/spec/unit/provider/service/freebsd_service_spec.rb +4 -4
- data/spec/unit/provider/service/init_service_spec.rb +26 -3
- data/spec/unit/provider/service/insserv_service_spec.rb +1 -1
- data/spec/unit/provider/service/invokercd_service_spec.rb +3 -3
- data/spec/unit/provider/service/redhat_spec.rb +1 -1
- data/spec/unit/provider/service/simple_service_spec.rb +3 -3
- data/spec/unit/provider/service/upstart_service_spec.rb +7 -7
- data/spec/unit/provider/service_spec.rb +2 -2
- data/spec/unit/provider/subversion_spec.rb +1 -1
- data/spec/unit/provider/template_spec.rb +35 -11
- data/spec/unit/provider/user/dscl_spec.rb +57 -31
- data/spec/unit/provider/user_spec.rb +7 -16
- data/spec/unit/provider_spec.rb +4 -3
- data/spec/unit/recipe_spec.rb +10 -8
- data/spec/unit/registry_helper_spec.rb +376 -0
- data/spec/unit/resource/log_spec.rb +9 -0
- data/spec/unit/resource/registry_key_spec.rb +171 -0
- data/spec/unit/resource/remote_file_spec.rb +21 -23
- data/spec/unit/resource/ruby_block_spec.rb +7 -3
- data/spec/unit/resource/service_spec.rb +11 -0
- data/spec/unit/resource_spec.rb +27 -4
- data/spec/unit/rest/auth_credentials_spec.rb +2 -14
- data/spec/unit/rest_spec.rb +122 -187
- data/spec/unit/run_context/cookbook_compiler_spec.rb +181 -0
- data/spec/unit/run_context_spec.rb +18 -4
- data/spec/unit/run_list_spec.rb +0 -209
- data/spec/unit/run_lock_spec.rb +37 -0
- data/spec/unit/runner_spec.rb +101 -2
- data/spec/unit/scan_access_control_spec.rb +4 -4
- data/spec/unit/{shef → shell}/model_wrapper_spec.rb +5 -5
- data/spec/unit/{shef/shef_ext_spec.rb → shell/shell_ext_spec.rb} +21 -21
- data/spec/unit/{shef/shef_session_spec.rb → shell/shell_session_spec.rb} +12 -12
- data/spec/unit/shell_out_spec.rb +18 -0
- data/spec/unit/{shef_spec.rb → shell_spec.rb} +20 -20
- data/spec/unit/user_spec.rb +255 -0
- metadata +162 -157
- data/README.rdoc +0 -177
- data/spec/unit/certificate_spec.rb +0 -76
- data/spec/unit/checksum_cache_spec.rb +0 -209
- data/spec/unit/checksum_spec.rb +0 -94
- data/spec/unit/couchdb_spec.rb +0 -274
- data/spec/unit/index_queue_spec.rb +0 -391
- data/spec/unit/json_compat_spect.rb +0 -53
- data/spec/unit/mixin/language_spec.rb +0 -305
- data/spec/unit/openid_registration_spec.rb +0 -153
- data/spec/unit/solr_query/query_transform_spec.rb +0 -454
- data/spec/unit/solr_query/solr_http_request_spec.rb +0 -244
- data/spec/unit/solr_query_spec.rb +0 -203
- data/spec/unit/webui_user_spec.rb +0 -238
@@ -0,0 +1,139 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Daniel DeLeo (<dan@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2012 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 "chef/node/immutable_collections"
|
21
|
+
|
22
|
+
describe Chef::Node::ImmutableMash do
|
23
|
+
before do
|
24
|
+
@data_in = {:top => {:second_level => "some value"},
|
25
|
+
"top_level_2" => %w[array of values],
|
26
|
+
:top_level_3 => [{:hash_array => 1, :hash_array_b => 2}],
|
27
|
+
:top_level_4 => {:level2 => {:key => "value"}}
|
28
|
+
}
|
29
|
+
@immutable_mash = Chef::Node::ImmutableMash.new(@data_in)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "element references like regular hash" do
|
33
|
+
@immutable_mash[:top][:second_level].should == "some value"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "elelment references like a regular Mash" do
|
37
|
+
@immutable_mash[:top_level_2].should == %w[array of values]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "converts Hash-like inputs into ImmutableMash's" do
|
41
|
+
@immutable_mash[:top].should be_a(Chef::Node::ImmutableMash)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "converts array inputs into ImmutableArray's" do
|
45
|
+
@immutable_mash[:top_level_2].should be_a(Chef::Node::ImmutableArray)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "converts arrays of hashes to ImmutableArray's of ImmutableMashes" do
|
49
|
+
@immutable_mash[:top_level_3].first.should be_a(Chef::Node::ImmutableMash)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "converts nested hashes to ImmutableMashes" do
|
53
|
+
@immutable_mash[:top_level_4].should be_a(Chef::Node::ImmutableMash)
|
54
|
+
@immutable_mash[:top_level_4][:level2].should be_a(Chef::Node::ImmutableMash)
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
[
|
59
|
+
:[]=,
|
60
|
+
:clear,
|
61
|
+
:default=,
|
62
|
+
:default_proc=,
|
63
|
+
:delete,
|
64
|
+
:delete_if,
|
65
|
+
:keep_if,
|
66
|
+
:merge!,
|
67
|
+
:update,
|
68
|
+
:reject!,
|
69
|
+
:replace,
|
70
|
+
:select!,
|
71
|
+
:shift
|
72
|
+
].each do |mutator|
|
73
|
+
it "doesn't allow mutation via `#{mutator}'" do
|
74
|
+
lambda { @immutable_mash.send(mutator) }.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
it "returns a mutable version of itself when duped" do
|
79
|
+
mutable = @immutable_mash.dup
|
80
|
+
mutable[:new_key] = :value
|
81
|
+
mutable[:new_key].should == :value
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
describe Chef::Node::ImmutableArray do
|
87
|
+
|
88
|
+
before do
|
89
|
+
@immutable_array = Chef::Node::ImmutableArray.new(%w[foo bar baz])
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Note: other behaviors, such as immutibilizing input data, are tested along
|
94
|
+
# with ImmutableMash, above
|
95
|
+
###
|
96
|
+
|
97
|
+
[
|
98
|
+
:<<,
|
99
|
+
:[]=,
|
100
|
+
:clear,
|
101
|
+
:collect!,
|
102
|
+
:compact!,
|
103
|
+
:default=,
|
104
|
+
:default_proc=,
|
105
|
+
:delete,
|
106
|
+
:delete_at,
|
107
|
+
:delete_if,
|
108
|
+
:fill,
|
109
|
+
:flatten!,
|
110
|
+
:insert,
|
111
|
+
:keep_if,
|
112
|
+
:map!,
|
113
|
+
:merge!,
|
114
|
+
:pop,
|
115
|
+
:push,
|
116
|
+
:update,
|
117
|
+
:reject!,
|
118
|
+
:reverse!,
|
119
|
+
:replace,
|
120
|
+
:select!,
|
121
|
+
:shift,
|
122
|
+
:slice!,
|
123
|
+
:sort!,
|
124
|
+
:sort_by!,
|
125
|
+
:uniq!,
|
126
|
+
:unshift
|
127
|
+
].each do |mutator|
|
128
|
+
it "does not allow mutation via `#{mutator}" do
|
129
|
+
lambda { @immutable_array.send(mutator)}.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
it "returns a mutable version of itself when duped" do
|
134
|
+
mutable = @immutable_array.dup
|
135
|
+
mutable[0] = :value
|
136
|
+
mutable[0].should == :value
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
data/spec/unit/node_spec.rb
CHANGED
@@ -20,10 +20,11 @@ require 'spec_helper'
|
|
20
20
|
require 'ostruct'
|
21
21
|
|
22
22
|
describe Chef::Node do
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
|
24
|
+
let(:node) { Chef::Node.new() }
|
25
|
+
let(:platform_introspector) { node }
|
26
|
+
|
27
|
+
it_behaves_like "a platform introspector"
|
27
28
|
|
28
29
|
it "creates a node and assigns it a name" do
|
29
30
|
node = Chef::Node.build('solo-node')
|
@@ -39,36 +40,33 @@ describe Chef::Node do
|
|
39
40
|
response = OpenStruct.new(:code => '404')
|
40
41
|
exception = Net::HTTPServerException.new("404 not found", response)
|
41
42
|
Chef::Node.stub!(:load).and_raise(exception)
|
42
|
-
|
43
|
+
node.name("created-node")
|
43
44
|
end
|
44
45
|
|
45
46
|
it "creates a new node for find_or_create" do
|
46
|
-
Chef::Node.stub!(:new).and_return(
|
47
|
-
|
47
|
+
Chef::Node.stub!(:new).and_return(node)
|
48
|
+
node.should_receive(:create).and_return(node)
|
48
49
|
node = Chef::Node.find_or_create("created-node")
|
49
50
|
node.name.should == 'created-node'
|
50
|
-
node.should equal(
|
51
|
+
node.should equal(node)
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
54
55
|
describe "when the node exists on the server" do
|
55
56
|
before do
|
56
|
-
|
57
|
-
Chef::Node.stub!(:load).and_return(
|
57
|
+
node.name('existing-node')
|
58
|
+
Chef::Node.stub!(:load).and_return(node)
|
58
59
|
end
|
59
60
|
|
60
61
|
it "loads the node via the REST API for find_or_create" do
|
61
|
-
Chef::Node.find_or_create('existing-node').should equal(
|
62
|
+
Chef::Node.find_or_create('existing-node').should equal(node)
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
65
66
|
describe "run_state" do
|
66
|
-
it "
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
it "should have a seen_recipes hash" do
|
71
|
-
@node.run_state[:seen_recipes].should be_a_kind_of(Hash)
|
67
|
+
it "is an empty hash" do
|
68
|
+
node.run_state.should respond_to(:keys)
|
69
|
+
node.run_state.should be_empty
|
72
70
|
end
|
73
71
|
end
|
74
72
|
|
@@ -81,180 +79,225 @@ describe Chef::Node do
|
|
81
79
|
|
82
80
|
describe "name" do
|
83
81
|
it "should allow you to set a name with name(something)" do
|
84
|
-
lambda {
|
82
|
+
lambda { node.name("latte") }.should_not raise_error
|
85
83
|
end
|
86
84
|
|
87
85
|
it "should return the name with name()" do
|
88
|
-
|
89
|
-
|
86
|
+
node.name("latte")
|
87
|
+
node.name.should eql("latte")
|
90
88
|
end
|
91
89
|
|
92
90
|
it "should always have a string for name" do
|
93
|
-
lambda {
|
91
|
+
lambda { node.name(Hash.new) }.should raise_error(ArgumentError)
|
94
92
|
end
|
95
93
|
|
96
94
|
it "cannot be blank" do
|
97
|
-
lambda {
|
95
|
+
lambda { node.name("")}.should raise_error(Chef::Exceptions::ValidationFailed)
|
98
96
|
end
|
99
97
|
|
100
98
|
it "should not accept name doesn't match /^[\-[:alnum:]_:.]+$/" do
|
101
|
-
lambda {
|
99
|
+
lambda { node.name("space in it")}.should raise_error(Chef::Exceptions::ValidationFailed)
|
102
100
|
end
|
103
101
|
end
|
104
102
|
|
105
103
|
describe "chef_environment" do
|
106
104
|
it "should set an environment with chef_environment(something)" do
|
107
|
-
lambda {
|
105
|
+
lambda { node.chef_environment("latte") }.should_not raise_error
|
108
106
|
end
|
109
107
|
|
110
108
|
it "should return the chef_environment with chef_environment()" do
|
111
|
-
|
112
|
-
|
109
|
+
node.chef_environment("latte")
|
110
|
+
node.chef_environment.should == "latte"
|
113
111
|
end
|
114
112
|
|
115
113
|
it "should disallow non-strings" do
|
116
|
-
lambda {
|
117
|
-
lambda {
|
114
|
+
lambda { node.chef_environment(Hash.new) }.should raise_error(ArgumentError)
|
115
|
+
lambda { node.chef_environment(42) }.should raise_error(ArgumentError)
|
118
116
|
end
|
119
117
|
|
120
118
|
it "cannot be blank" do
|
121
|
-
lambda {
|
119
|
+
lambda { node.chef_environment("")}.should raise_error(Chef::Exceptions::ValidationFailed)
|
122
120
|
end
|
123
121
|
end
|
124
122
|
|
125
123
|
describe "attributes" do
|
126
|
-
it "should be loaded from the node's cookbooks" do
|
127
|
-
@cookbook_repo = File.expand_path(File.join(File.dirname(__FILE__), "..", "data", "cookbooks"))
|
128
|
-
@node.cookbook_collection = Chef::CookbookCollection.new(Chef::CookbookLoader.new(@cookbook_repo))
|
129
|
-
@node.load_attributes
|
130
|
-
@node.ldap_server.should eql("ops1prod")
|
131
|
-
@node.ldap_basedn.should eql("dc=hjksolutions,dc=com")
|
132
|
-
@node.ldap_replication_password.should eql("forsure")
|
133
|
-
@node.smokey.should eql("robinson")
|
134
|
-
end
|
135
|
-
|
136
124
|
it "should have attributes" do
|
137
|
-
|
125
|
+
node.attribute.should be_a_kind_of(Hash)
|
138
126
|
end
|
139
127
|
|
140
128
|
it "should allow attributes to be accessed by name or symbol directly on node[]" do
|
141
|
-
|
142
|
-
|
143
|
-
|
129
|
+
node.default["locust"] = "something"
|
130
|
+
node[:locust].should eql("something")
|
131
|
+
node["locust"].should eql("something")
|
144
132
|
end
|
145
133
|
|
146
134
|
it "should return nil if it cannot find an attribute with node[]" do
|
147
|
-
|
135
|
+
node["secret"].should eql(nil)
|
148
136
|
end
|
149
137
|
|
150
|
-
it "
|
151
|
-
|
152
|
-
@node["secret"].should eql("shush")
|
138
|
+
it "does not allow you to set an attribute via node[]=" do
|
139
|
+
lambda { node["secret"] = "shush" }.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
|
153
140
|
end
|
154
141
|
|
155
142
|
it "should allow you to query whether an attribute exists with attribute?" do
|
156
|
-
|
157
|
-
|
158
|
-
|
143
|
+
node.default["locust"] = "something"
|
144
|
+
node.attribute?("locust").should eql(true)
|
145
|
+
node.attribute?("no dice").should eql(false)
|
159
146
|
end
|
160
147
|
|
161
148
|
it "should let you go deep with attribute?" do
|
162
|
-
|
163
|
-
|
164
|
-
|
149
|
+
node.set["battles"]["people"]["wonkey"] = true
|
150
|
+
node["battles"]["people"].attribute?("wonkey").should == true
|
151
|
+
node["battles"]["people"].attribute?("snozzberry").should == false
|
165
152
|
end
|
166
153
|
|
167
|
-
it "
|
168
|
-
|
169
|
-
@node.attribute[:sunshine].should eql("is bright")
|
154
|
+
it "does not allow you to set an attribute via method_missing" do
|
155
|
+
lambda { node.sunshine = "is bright"}.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
|
170
156
|
end
|
171
157
|
|
172
158
|
it "should allow you get get an attribute via method_missing" do
|
173
|
-
|
174
|
-
|
159
|
+
node.default.sunshine = "is bright"
|
160
|
+
node.sunshine.should eql("is bright")
|
175
161
|
end
|
176
162
|
|
177
163
|
describe "normal attributes" do
|
178
164
|
it "should allow you to set an attribute with set, without pre-declaring a hash" do
|
179
|
-
|
180
|
-
|
165
|
+
node.set[:snoopy][:is_a_puppy] = true
|
166
|
+
node[:snoopy][:is_a_puppy].should == true
|
181
167
|
end
|
182
168
|
|
183
169
|
it "should allow you to set an attribute with set_unless" do
|
184
|
-
|
185
|
-
|
170
|
+
node.set_unless[:snoopy][:is_a_puppy] = false
|
171
|
+
node[:snoopy][:is_a_puppy].should == false
|
186
172
|
end
|
187
173
|
|
188
174
|
it "should not allow you to set an attribute with set_unless if it already exists" do
|
189
|
-
|
190
|
-
|
191
|
-
|
175
|
+
node.set[:snoopy][:is_a_puppy] = true
|
176
|
+
node.set_unless[:snoopy][:is_a_puppy] = false
|
177
|
+
node[:snoopy][:is_a_puppy].should == true
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should allow you to set a value after a set_unless" do
|
181
|
+
# this tests for set_unless_present state bleeding between statements CHEF-3806
|
182
|
+
node.set_unless[:snoopy][:is_a_puppy] = false
|
183
|
+
node.set[:snoopy][:is_a_puppy] = true
|
184
|
+
node[:snoopy][:is_a_puppy].should == true
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should let you set a value after a 'dangling' set_unless" do
|
188
|
+
# this tests for set_unless_present state bleeding between statements CHEF-3806
|
189
|
+
node.set[:snoopy][:is_a_puppy] = "what"
|
190
|
+
node.set_unless[:snoopy][:is_a_puppy]
|
191
|
+
node.set[:snoopy][:is_a_puppy] = true
|
192
|
+
node[:snoopy][:is_a_puppy].should == true
|
192
193
|
end
|
193
194
|
|
194
195
|
it "auto-vivifies attributes created via method syntax" do
|
195
|
-
|
196
|
-
|
196
|
+
node.set.fuu.bahrr.baz = "qux"
|
197
|
+
node.fuu.bahrr.baz.should == "qux"
|
197
198
|
end
|
198
199
|
|
199
200
|
end
|
200
201
|
|
201
202
|
describe "default attributes" do
|
202
203
|
it "should be set with default, without pre-declaring a hash" do
|
203
|
-
|
204
|
-
|
204
|
+
node.default[:snoopy][:is_a_puppy] = true
|
205
|
+
node[:snoopy][:is_a_puppy].should == true
|
205
206
|
end
|
206
207
|
|
207
208
|
it "should allow you to set with default_unless without pre-declaring a hash" do
|
208
|
-
|
209
|
-
|
209
|
+
node.default_unless[:snoopy][:is_a_puppy] = false
|
210
|
+
node[:snoopy][:is_a_puppy].should == false
|
210
211
|
end
|
211
212
|
|
212
213
|
it "should not allow you to set an attribute with default_unless if it already exists" do
|
213
|
-
|
214
|
-
|
215
|
-
|
214
|
+
node.default[:snoopy][:is_a_puppy] = true
|
215
|
+
node.default_unless[:snoopy][:is_a_puppy] = false
|
216
|
+
node[:snoopy][:is_a_puppy].should == true
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should allow you to set a value after a default_unless" do
|
220
|
+
# this tests for set_unless_present state bleeding between statements CHEF-3806
|
221
|
+
node.default_unless[:snoopy][:is_a_puppy] = false
|
222
|
+
node.default[:snoopy][:is_a_puppy] = true
|
223
|
+
node[:snoopy][:is_a_puppy].should == true
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should allow you to set a value after a 'dangling' default_unless" do
|
227
|
+
# this tests for set_unless_present state bleeding between statements CHEF-3806
|
228
|
+
node.default[:snoopy][:is_a_puppy] = "what"
|
229
|
+
node.default_unless[:snoopy][:is_a_puppy]
|
230
|
+
node.default[:snoopy][:is_a_puppy] = true
|
231
|
+
node[:snoopy][:is_a_puppy].should == true
|
216
232
|
end
|
217
233
|
|
218
234
|
it "auto-vivifies attributes created via method syntax" do
|
219
|
-
|
220
|
-
|
235
|
+
node.default.fuu.bahrr.baz = "qux"
|
236
|
+
node.fuu.bahrr.baz.should == "qux"
|
237
|
+
end
|
238
|
+
|
239
|
+
it "accesses force defaults via default!" do
|
240
|
+
node.default![:foo] = "wet bar"
|
241
|
+
node.default[:foo] = "bar"
|
242
|
+
node[:foo].should == "wet bar"
|
221
243
|
end
|
222
244
|
|
223
245
|
end
|
224
246
|
|
225
247
|
describe "override attributes" do
|
226
248
|
it "should be set with override, without pre-declaring a hash" do
|
227
|
-
|
228
|
-
|
249
|
+
node.override[:snoopy][:is_a_puppy] = true
|
250
|
+
node[:snoopy][:is_a_puppy].should == true
|
229
251
|
end
|
230
252
|
|
231
253
|
it "should allow you to set with override_unless without pre-declaring a hash" do
|
232
|
-
|
233
|
-
|
254
|
+
node.override_unless[:snoopy][:is_a_puppy] = false
|
255
|
+
node[:snoopy][:is_a_puppy].should == false
|
234
256
|
end
|
235
257
|
|
236
258
|
it "should not allow you to set an attribute with override_unless if it already exists" do
|
237
|
-
|
238
|
-
|
239
|
-
|
259
|
+
node.override[:snoopy][:is_a_puppy] = true
|
260
|
+
node.override_unless[:snoopy][:is_a_puppy] = false
|
261
|
+
node[:snoopy][:is_a_puppy].should == true
|
262
|
+
end
|
263
|
+
|
264
|
+
it "should allow you to set a value after an override_unless" do
|
265
|
+
# this tests for set_unless_present state bleeding between statements CHEF-3806
|
266
|
+
node.override_unless[:snoopy][:is_a_puppy] = false
|
267
|
+
node.override[:snoopy][:is_a_puppy] = true
|
268
|
+
node[:snoopy][:is_a_puppy].should == true
|
269
|
+
end
|
270
|
+
|
271
|
+
it "should allow you to set a value after a 'dangling' override_unless" do
|
272
|
+
# this tests for set_unless_present state bleeding between statements CHEF-3806
|
273
|
+
node.override_unless[:snoopy][:is_a_puppy] = "what"
|
274
|
+
node.override_unless[:snoopy][:is_a_puppy]
|
275
|
+
node.override[:snoopy][:is_a_puppy] = true
|
276
|
+
node[:snoopy][:is_a_puppy].should == true
|
240
277
|
end
|
241
278
|
|
242
279
|
it "auto-vivifies attributes created via method syntax" do
|
243
|
-
|
244
|
-
|
280
|
+
node.override.fuu.bahrr.baz = "qux"
|
281
|
+
node.fuu.bahrr.baz.should == "qux"
|
282
|
+
end
|
283
|
+
|
284
|
+
it "sets force_overrides via override!" do
|
285
|
+
node.override![:foo] = "wet bar"
|
286
|
+
node.override[:foo] = "bar"
|
287
|
+
node[:foo].should == "wet bar"
|
245
288
|
end
|
246
289
|
|
247
290
|
end
|
248
291
|
|
249
292
|
it "should raise an ArgumentError if you ask for an attribute that doesn't exist via method_missing" do
|
250
|
-
lambda {
|
293
|
+
lambda { node.sunshine }.should raise_error(NoMethodError)
|
251
294
|
end
|
252
295
|
|
253
296
|
it "should allow you to iterate over attributes with each_attribute" do
|
254
|
-
|
255
|
-
|
297
|
+
node.default.sunshine = "is bright"
|
298
|
+
node.default.canada = "is a nice place"
|
256
299
|
seen_attributes = Hash.new
|
257
|
-
|
300
|
+
node.each_attribute do |a,v|
|
258
301
|
seen_attributes[a] = v
|
259
302
|
end
|
260
303
|
seen_attributes.should have_key("sunshine")
|
@@ -272,62 +315,62 @@ describe Chef::Node do
|
|
272
315
|
|
273
316
|
it "consumes the run list portion of a collection of attributes and returns the remainder" do
|
274
317
|
attrs = {"run_list" => [ "role[base]", "recipe[chef::server]" ], "foo" => "bar"}
|
275
|
-
|
276
|
-
|
318
|
+
node.consume_run_list(attrs).should == {"foo" => "bar"}
|
319
|
+
node.run_list.should == [ "role[base]", "recipe[chef::server]" ]
|
277
320
|
end
|
278
321
|
|
279
322
|
it "should overwrites the run list with the run list it consumes" do
|
280
|
-
|
281
|
-
|
282
|
-
|
323
|
+
node.consume_run_list "recipes" => [ "one", "two" ]
|
324
|
+
node.consume_run_list "recipes" => [ "three" ]
|
325
|
+
node.run_list.should == [ "three" ]
|
283
326
|
end
|
284
327
|
|
285
328
|
it "should not add duplicate recipes from the json attributes" do
|
286
|
-
|
287
|
-
|
288
|
-
|
329
|
+
node.run_list << "one"
|
330
|
+
node.consume_run_list "recipes" => [ "one", "two", "three" ]
|
331
|
+
node.run_list.should == [ "one", "two", "three" ]
|
289
332
|
end
|
290
333
|
|
291
334
|
it "doesn't change the run list if no run_list is specified in the json" do
|
292
|
-
|
293
|
-
|
294
|
-
|
335
|
+
node.run_list << "role[database]"
|
336
|
+
node.consume_run_list "foo" => "bar"
|
337
|
+
node.run_list.should == ["role[database]"]
|
295
338
|
end
|
296
339
|
|
297
340
|
it "raises an exception if you provide both recipe and run_list attributes, since this is ambiguous" do
|
298
|
-
lambda {
|
341
|
+
lambda { node.consume_run_list "recipes" => "stuff", "run_list" => "other_stuff" }.should raise_error(Chef::Exceptions::AmbiguousRunlistSpecification)
|
299
342
|
end
|
300
343
|
|
301
344
|
it "should add json attributes to the node" do
|
302
|
-
|
303
|
-
|
304
|
-
|
345
|
+
node.consume_external_attrs(@ohai_data, {"one" => "two", "three" => "four"})
|
346
|
+
node.one.should eql("two")
|
347
|
+
node.three.should eql("four")
|
305
348
|
end
|
306
349
|
|
307
350
|
it "should set the tags attribute to an empty array if it is not already defined" do
|
308
|
-
|
309
|
-
|
351
|
+
node.consume_external_attrs(@ohai_data, {})
|
352
|
+
node.tags.should eql([])
|
310
353
|
end
|
311
354
|
|
312
355
|
it "should not set the tags attribute to an empty array if it is already defined" do
|
313
|
-
|
314
|
-
|
315
|
-
|
356
|
+
node.normal[:tags] = [ "radiohead" ]
|
357
|
+
node.consume_external_attrs(@ohai_data, {})
|
358
|
+
node.tags.should eql([ "radiohead" ])
|
316
359
|
end
|
317
360
|
|
318
361
|
it "deep merges attributes instead of overwriting them" do
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
362
|
+
node.consume_external_attrs(@ohai_data, "one" => {"two" => {"three" => "four"}})
|
363
|
+
node.one.to_hash.should == {"two" => {"three" => "four"}}
|
364
|
+
node.consume_external_attrs(@ohai_data, "one" => {"abc" => "123"})
|
365
|
+
node.consume_external_attrs(@ohai_data, "one" => {"two" => {"foo" => "bar"}})
|
366
|
+
node.one.to_hash.should == {"two" => {"three" => "four", "foo" => "bar"}, "abc" => "123"}
|
324
367
|
end
|
325
368
|
|
326
369
|
it "gives attributes from JSON priority when deep merging" do
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
370
|
+
node.consume_external_attrs(@ohai_data, "one" => {"two" => {"three" => "four"}})
|
371
|
+
node.one.to_hash.should == {"two" => {"three" => "four"}}
|
372
|
+
node.consume_external_attrs(@ohai_data, "one" => {"two" => {"three" => "forty-two"}})
|
373
|
+
node.one.to_hash.should == {"two" => {"three" => "forty-two"}}
|
331
374
|
end
|
332
375
|
|
333
376
|
end
|
@@ -338,161 +381,249 @@ describe Chef::Node do
|
|
338
381
|
end
|
339
382
|
|
340
383
|
it "sets its platform according to platform detection" do
|
341
|
-
|
342
|
-
|
343
|
-
|
384
|
+
node.consume_external_attrs(@ohai_data, {})
|
385
|
+
node.automatic_attrs[:platform].should == 'foobuntu'
|
386
|
+
node.automatic_attrs[:platform_version].should == '23.42'
|
344
387
|
end
|
345
388
|
|
346
389
|
it "consumes the run list from provided json attributes" do
|
347
|
-
|
348
|
-
|
390
|
+
node.consume_external_attrs(@ohai_data, {"run_list" => ['recipe[unicorn]']})
|
391
|
+
node.run_list.should == ['recipe[unicorn]']
|
349
392
|
end
|
350
393
|
|
351
394
|
it "saves non-runlist json attrs for later" do
|
352
395
|
expansion = Chef::RunList::RunListExpansion.new('_default', [])
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
396
|
+
node.run_list.stub!(:expand).and_return(expansion)
|
397
|
+
node.consume_external_attrs(@ohai_data, {"foo" => "bar"})
|
398
|
+
node.expand!
|
399
|
+
node.normal_attrs.should == {"foo" => "bar", "tags" => []}
|
357
400
|
end
|
358
401
|
|
359
402
|
end
|
360
403
|
|
361
404
|
describe "when expanding its run list and merging attributes" do
|
362
405
|
before do
|
363
|
-
@
|
364
|
-
|
406
|
+
@environment = Chef::Environment.new.tap do |e|
|
407
|
+
e.name('rspec_env')
|
408
|
+
e.default_attributes("env default key" => "env default value")
|
409
|
+
e.override_attributes("env override key" => "env override value")
|
410
|
+
end
|
411
|
+
Chef::Environment.should_receive(:load).with("rspec_env").and_return(@environment)
|
412
|
+
@expansion = Chef::RunList::RunListExpansion.new("rspec_env", [])
|
413
|
+
node.chef_environment("rspec_env")
|
414
|
+
node.run_list.stub!(:expand).and_return(@expansion)
|
365
415
|
end
|
366
416
|
|
367
417
|
it "sets the 'recipes' automatic attribute to the recipes in the expanded run_list" do
|
368
418
|
@expansion.recipes << 'recipe[chef::client]' << 'recipe[nginx::default]'
|
369
|
-
|
370
|
-
|
419
|
+
node.expand!
|
420
|
+
node.automatic_attrs[:recipes].should == ['recipe[chef::client]', 'recipe[nginx::default]']
|
371
421
|
end
|
372
422
|
|
373
423
|
it "sets the 'roles' automatic attribute to the expanded role list" do
|
374
424
|
@expansion.instance_variable_set(:@applied_roles, {'arf' => nil, 'countersnark' => nil})
|
375
|
-
|
376
|
-
|
425
|
+
node.expand!
|
426
|
+
node.automatic_attrs[:roles].sort.should == ['arf', 'countersnark']
|
427
|
+
end
|
428
|
+
|
429
|
+
it "applies default attributes from the environment as environment defaults" do
|
430
|
+
node.expand!
|
431
|
+
node.attributes.env_default["env default key"].should == "env default value"
|
432
|
+
end
|
433
|
+
|
434
|
+
it "applies override attributes from the environment as env overrides" do
|
435
|
+
node.expand!
|
436
|
+
node.attributes.env_override["env override key"].should == "env override value"
|
437
|
+
end
|
438
|
+
|
439
|
+
it "applies default attributes from roles as role defaults" do
|
440
|
+
@expansion.default_attrs["role default key"] = "role default value"
|
441
|
+
node.expand!
|
442
|
+
node.attributes.role_default["role default key"].should == "role default value"
|
377
443
|
end
|
378
444
|
|
445
|
+
it "applies override attributes from roles as role overrides" do
|
446
|
+
@expansion.override_attrs["role override key"] = "role override value"
|
447
|
+
node.expand!
|
448
|
+
node.attributes.role_override["role override key"].should == "role override value"
|
449
|
+
end
|
379
450
|
end
|
380
451
|
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
452
|
+
describe "when querying for recipes in the run list" do
|
453
|
+
context "when a recipe is in the top level run list" do
|
454
|
+
before do
|
455
|
+
node.run_list << "recipe[nginx::module]"
|
456
|
+
end
|
457
|
+
|
458
|
+
it "finds the recipe" do
|
459
|
+
node.recipe?("nginx::module").should be_true
|
460
|
+
end
|
461
|
+
|
462
|
+
it "does not find a recipe not in the run list" do
|
463
|
+
node.recipe?("nginx::other_module").should be_false
|
464
|
+
end
|
465
|
+
end
|
466
|
+
context "when a recipe is in the expanded run list only" do
|
467
|
+
before do
|
468
|
+
node.run_list << "role[base]"
|
469
|
+
node.automatic_attrs[:recipes] = [ "nginx::module" ]
|
470
|
+
end
|
471
|
+
|
472
|
+
it "finds a recipe in the expanded run list" do
|
473
|
+
node.recipe?("nginx::module").should be_true
|
474
|
+
end
|
475
|
+
|
476
|
+
it "does not find a recipe that's not in the run list" do
|
477
|
+
node.recipe?("nginx::other_module").should be_false
|
478
|
+
end
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
describe "when clearing computed state at the beginning of a run" do
|
483
|
+
before do
|
484
|
+
node.default[:foo] = "default"
|
485
|
+
node.normal[:foo] = "normal"
|
486
|
+
node.override[:foo] = "override"
|
487
|
+
node.reset_defaults_and_overrides
|
488
|
+
end
|
489
|
+
|
490
|
+
it "removes default attributes" do
|
491
|
+
node.default.should be_empty
|
492
|
+
end
|
493
|
+
|
494
|
+
it "removes override attributes" do
|
495
|
+
node.override.should be_empty
|
496
|
+
end
|
497
|
+
|
498
|
+
it "leaves normal level attributes untouched" do
|
499
|
+
node[:foo].should == "normal"
|
500
|
+
end
|
501
|
+
|
502
|
+
end
|
503
|
+
|
504
|
+
describe "when merging environment attributes" do
|
505
|
+
before do
|
506
|
+
node.chef_environment = "rspec"
|
507
|
+
@expansion = Chef::RunList::RunListExpansion.new("rspec", [])
|
508
|
+
@expansion.default_attrs.replace({:default => "from role", :d_role => "role only"})
|
509
|
+
@expansion.override_attrs.replace({:override => "from role", :o_role => "role only"})
|
510
|
+
|
511
|
+
|
512
|
+
@environment = Chef::Environment.new
|
513
|
+
@environment.default_attributes = {:default => "from env", :d_env => "env only" }
|
514
|
+
@environment.override_attributes = {:override => "from env", :o_env => "env only"}
|
515
|
+
Chef::Environment.stub!(:load).and_return(@environment)
|
516
|
+
node.apply_expansion_attributes(@expansion)
|
517
|
+
end
|
518
|
+
|
519
|
+
it "does not nuke role-only default attrs" do
|
520
|
+
node[:d_role].should == "role only"
|
521
|
+
end
|
522
|
+
|
523
|
+
it "does not nuke role-only override attrs" do
|
524
|
+
node[:o_role].should == "role only"
|
525
|
+
end
|
526
|
+
|
527
|
+
it "does not nuke env-only default attrs" do
|
528
|
+
node[:o_env].should == "env only"
|
529
|
+
end
|
530
|
+
|
531
|
+
it "does not nuke role-only override attrs" do
|
532
|
+
node[:o_env].should == "env only"
|
533
|
+
end
|
534
|
+
|
535
|
+
it "gives role defaults precedence over env defaults" do
|
536
|
+
node[:default].should == "from role"
|
537
|
+
end
|
538
|
+
|
539
|
+
it "gives env overrides precedence over role overrides" do
|
540
|
+
node[:override].should == "from env"
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
describe "when evaluating attributes files" do
|
545
|
+
before do
|
546
|
+
@cookbook_repo = File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks"))
|
547
|
+
@cookbook_loader = Chef::CookbookLoader.new(@cookbook_repo)
|
548
|
+
@cookbook_loader.load_cookbooks
|
549
|
+
|
550
|
+
@cookbook_collection = Chef::CookbookCollection.new(@cookbook_loader.cookbooks_by_name)
|
551
|
+
|
552
|
+
@events = Chef::EventDispatch::Dispatcher.new
|
553
|
+
@run_context = Chef::RunContext.new(node, @cookbook_collection, @events)
|
554
|
+
|
555
|
+
node.include_attribute("openldap::default")
|
556
|
+
node.include_attribute("openldap::smokey")
|
557
|
+
end
|
558
|
+
|
559
|
+
it "sets attributes from the files" do
|
560
|
+
node.ldap_server.should eql("ops1prod")
|
561
|
+
node.ldap_basedn.should eql("dc=hjksolutions,dc=com")
|
562
|
+
node.ldap_replication_password.should eql("forsure")
|
563
|
+
node.smokey.should eql("robinson")
|
564
|
+
end
|
565
|
+
|
566
|
+
it "gives a sensible error when attempting to load a missing attributes file" do
|
567
|
+
lambda { node.include_attribute("nope-this::doesnt-exist") }.should raise_error(Chef::Exceptions::CookbookNotFound)
|
568
|
+
end
|
569
|
+
end
|
408
570
|
|
409
571
|
describe "roles" do
|
410
572
|
it "should allow you to query whether or not it has a recipe applied with role?" do
|
411
|
-
|
412
|
-
|
413
|
-
|
573
|
+
node.run_list << "role[sunrise]"
|
574
|
+
node.role?("sunrise").should eql(true)
|
575
|
+
node.role?("not at home").should eql(false)
|
414
576
|
end
|
415
577
|
|
416
578
|
it "should allow you to set roles with arguments" do
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
579
|
+
node.run_list << "role[one]"
|
580
|
+
node.run_list << "role[two]"
|
581
|
+
node.role?("one").should eql(true)
|
582
|
+
node.role?("two").should eql(true)
|
421
583
|
end
|
422
584
|
end
|
423
585
|
|
424
586
|
describe "run_list" do
|
425
587
|
it "should have a Chef::RunList of recipes and roles that should be applied" do
|
426
|
-
|
588
|
+
node.run_list.should be_a_kind_of(Chef::RunList)
|
427
589
|
end
|
428
590
|
|
429
591
|
it "should allow you to query the run list with arguments" do
|
430
|
-
|
431
|
-
|
592
|
+
node.run_list "recipe[baz]"
|
593
|
+
node.run_list?("recipe[baz]").should eql(true)
|
432
594
|
end
|
433
595
|
|
434
596
|
it "should allow you to set the run list with arguments" do
|
435
|
-
|
436
|
-
|
437
|
-
|
597
|
+
node.run_list "recipe[baz]", "role[foo]"
|
598
|
+
node.run_list?("recipe[baz]").should eql(true)
|
599
|
+
node.run_list?("role[foo]").should eql(true)
|
438
600
|
end
|
439
601
|
end
|
440
602
|
|
441
603
|
describe "from file" do
|
442
604
|
it "should load a node from a ruby file" do
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
605
|
+
node.from_file(File.expand_path(File.join(CHEF_SPEC_DATA, "nodes", "test.rb")))
|
606
|
+
node.name.should eql("test.example.com-short")
|
607
|
+
node.sunshine.should eql("in")
|
608
|
+
node.something.should eql("else")
|
609
|
+
node.run_list.should == ["operations-master", "operations-monitoring"]
|
448
610
|
end
|
449
611
|
|
450
612
|
it "should raise an exception if the file cannot be found or read" do
|
451
|
-
lambda {
|
452
|
-
end
|
453
|
-
end
|
454
|
-
|
455
|
-
describe "find_file" do
|
456
|
-
it "should load a node from a file by fqdn" do
|
457
|
-
@node.find_file("test.example.com")
|
458
|
-
@node.name.should == "test.example.com"
|
459
|
-
@node.chef_environment.should == "dev"
|
460
|
-
end
|
461
|
-
|
462
|
-
it "should load a node from a file by hostname" do
|
463
|
-
File.stub!(:exists?).and_return(true)
|
464
|
-
File.should_receive(:exists?).with(File.join(Chef::Config[:node_path], "test.example.com.rb")).and_return(false)
|
465
|
-
@node.find_file("test.example.com")
|
466
|
-
@node.name.should == "test.example.com-short"
|
467
|
-
end
|
468
|
-
|
469
|
-
it "should load a node from the default file" do
|
470
|
-
File.stub!(:exists?).and_return(true)
|
471
|
-
File.should_receive(:exists?).with(File.join(Chef::Config[:node_path], "test.example.com.rb")).and_return(false)
|
472
|
-
File.should_receive(:exists?).with(File.join(Chef::Config[:node_path], "test.rb")).and_return(false)
|
473
|
-
@node.find_file("test.example.com")
|
474
|
-
@node.name.should == "test.example.com-default"
|
475
|
-
end
|
476
|
-
|
477
|
-
it "should raise an ArgumentError if it cannot find any node file at all" do
|
478
|
-
File.stub!(:exists?).and_return(true)
|
479
|
-
File.should_receive(:exists?).with(File.join(Chef::Config[:node_path], "test.example.com.rb")).and_return(false)
|
480
|
-
File.should_receive(:exists?).with(File.join(Chef::Config[:node_path], "test.rb")).and_return(false)
|
481
|
-
File.should_receive(:exists?).with(File.join(Chef::Config[:node_path], "default.rb")).and_return(false)
|
482
|
-
lambda { @node.find_file("test.example.com") }.should raise_error(ArgumentError)
|
613
|
+
lambda { node.from_file("/tmp/monkeydiving") }.should raise_error(IOError)
|
483
614
|
end
|
484
615
|
end
|
485
616
|
|
486
617
|
describe "update_from!" do
|
487
618
|
before(:each) do
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
619
|
+
node.name("orig")
|
620
|
+
node.chef_environment("dev")
|
621
|
+
node.default_attrs = { "one" => { "two" => "three", "four" => "five", "eight" => "nine" } }
|
622
|
+
node.override_attrs = { "one" => { "two" => "three", "four" => "six" } }
|
623
|
+
node.normal_attrs = { "one" => { "two" => "seven" } }
|
624
|
+
node.run_list << "role[marxist]"
|
625
|
+
node.run_list << "role[leninist]"
|
626
|
+
node.run_list << "recipe[stalinist]"
|
496
627
|
|
497
628
|
@example = Chef::Node.new()
|
498
629
|
@example.name("newname")
|
@@ -506,31 +637,31 @@ describe Chef::Node do
|
|
506
637
|
end
|
507
638
|
|
508
639
|
it "allows update of everything except name" do
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
640
|
+
node.update_from!(@example)
|
641
|
+
node.name.should == "orig"
|
642
|
+
node.chef_environment.should == @example.chef_environment
|
643
|
+
node.default_attrs.should == @example.default_attrs
|
644
|
+
node.override_attrs.should == @example.override_attrs
|
645
|
+
node.normal_attrs.should == @example.normal_attrs
|
646
|
+
node.run_list.should == @example.run_list
|
516
647
|
end
|
517
648
|
|
518
649
|
it "should not update the name of the node" do
|
519
|
-
|
520
|
-
|
650
|
+
node.should_not_receive(:name).with(@example.name)
|
651
|
+
node.update_from!(@example)
|
521
652
|
end
|
522
653
|
end
|
523
654
|
|
524
655
|
describe "to_hash" do
|
525
656
|
it "should serialize itself as a hash" do
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
h =
|
657
|
+
node.chef_environment("dev")
|
658
|
+
node.default_attrs = { "one" => { "two" => "three", "four" => "five", "eight" => "nine" } }
|
659
|
+
node.override_attrs = { "one" => { "two" => "three", "four" => "six" } }
|
660
|
+
node.normal_attrs = { "one" => { "two" => "seven" } }
|
661
|
+
node.run_list << "role[marxist]"
|
662
|
+
node.run_list << "role[leninist]"
|
663
|
+
node.run_list << "recipe[stalinist]"
|
664
|
+
h = node.to_hash
|
534
665
|
h["one"]["two"].should == "three"
|
535
666
|
h["one"]["four"].should == "six"
|
536
667
|
h["one"]["eight"].should == "nine"
|
@@ -543,10 +674,10 @@ describe Chef::Node do
|
|
543
674
|
end
|
544
675
|
end
|
545
676
|
|
546
|
-
describe "json" do
|
677
|
+
describe "converting to or from json" do
|
547
678
|
it "should serialize itself as json", :json => true do
|
548
|
-
|
549
|
-
json = Chef::JSONCompat.to_json(
|
679
|
+
node.from_file(File.expand_path("nodes/test.example.com.rb", CHEF_SPEC_DATA))
|
680
|
+
json = Chef::JSONCompat.to_json(node)
|
550
681
|
json.should =~ /json_class/
|
551
682
|
json.should =~ /name/
|
552
683
|
json.should =~ /chef_environment/
|
@@ -556,33 +687,50 @@ describe Chef::Node do
|
|
556
687
|
json.should =~ /run_list/
|
557
688
|
end
|
558
689
|
|
559
|
-
it 'should
|
690
|
+
it 'should serialize valid json with a run list', :json => true do
|
560
691
|
#This test came about because activesupport mucks with Chef json serialization
|
561
692
|
#Test should pass with and without Activesupport
|
562
|
-
|
563
|
-
|
564
|
-
json = Chef::JSONCompat.to_json(
|
693
|
+
node.run_list << {"type" => "role", "name" => 'Cthulu'}
|
694
|
+
node.run_list << {"type" => "role", "name" => 'Hastur'}
|
695
|
+
json = Chef::JSONCompat.to_json(node)
|
565
696
|
json.should =~ /\"run_list\":\[\"role\[Cthulu\]\",\"role\[Hastur\]\"\]/
|
566
697
|
end
|
567
698
|
|
699
|
+
it "merges the override components into a combined override object" do
|
700
|
+
node.attributes.role_override["role override"] = "role override"
|
701
|
+
node.attributes.env_override["env override"] = "env override"
|
702
|
+
node_for_json = node.for_json
|
703
|
+
node_for_json["override"]["role override"].should == "role override"
|
704
|
+
node_for_json["override"]["env override"].should == "env override"
|
705
|
+
end
|
706
|
+
|
707
|
+
it "merges the default components into a combined default object" do
|
708
|
+
node.attributes.role_default["role default"] = "role default"
|
709
|
+
node.attributes.env_default["env default"] = "env default"
|
710
|
+
node_for_json = node.for_json
|
711
|
+
node_for_json["default"]["role default"].should == "role default"
|
712
|
+
node_for_json["default"]["env default"].should == "env default"
|
713
|
+
end
|
714
|
+
|
715
|
+
|
568
716
|
it "should deserialize itself from json", :json => true do
|
569
|
-
|
570
|
-
json = Chef::JSONCompat.to_json(
|
717
|
+
node.from_file(File.expand_path("nodes/test.example.com.rb", CHEF_SPEC_DATA))
|
718
|
+
json = Chef::JSONCompat.to_json(node)
|
571
719
|
serialized_node = Chef::JSONCompat.from_json(json)
|
572
720
|
serialized_node.should be_a_kind_of(Chef::Node)
|
573
|
-
serialized_node.name.should eql(
|
574
|
-
serialized_node.chef_environment.should eql(
|
575
|
-
|
721
|
+
serialized_node.name.should eql(node.name)
|
722
|
+
serialized_node.chef_environment.should eql(node.chef_environment)
|
723
|
+
node.each_attribute do |k,v|
|
576
724
|
serialized_node[k].should eql(v)
|
577
725
|
end
|
578
|
-
serialized_node.run_list.should ==
|
726
|
+
serialized_node.run_list.should == node.run_list
|
579
727
|
end
|
580
728
|
end
|
581
729
|
|
582
730
|
describe "to_s" do
|
583
731
|
it "should turn into a string like node[name]" do
|
584
|
-
|
585
|
-
|
732
|
+
node.name("airplane")
|
733
|
+
node.to_s.should eql("node[airplane]")
|
586
734
|
end
|
587
735
|
end
|
588
736
|
|
@@ -621,31 +769,31 @@ describe Chef::Node do
|
|
621
769
|
describe "destroy" do
|
622
770
|
it "should destroy a node" do
|
623
771
|
@rest.should_receive(:delete_rest).with("nodes/monkey").and_return("foo")
|
624
|
-
|
625
|
-
|
772
|
+
node.name("monkey")
|
773
|
+
node.destroy
|
626
774
|
end
|
627
775
|
end
|
628
776
|
|
629
777
|
describe "save" do
|
630
778
|
it "should update a node if it already exists" do
|
631
|
-
|
632
|
-
@rest.should_receive(:put_rest).with("nodes/monkey",
|
633
|
-
|
779
|
+
node.name("monkey")
|
780
|
+
@rest.should_receive(:put_rest).with("nodes/monkey", node).and_return("foo")
|
781
|
+
node.save
|
634
782
|
end
|
635
783
|
|
636
784
|
it "should not try and create if it can update" do
|
637
|
-
|
638
|
-
@rest.should_receive(:put_rest).with("nodes/monkey",
|
785
|
+
node.name("monkey")
|
786
|
+
@rest.should_receive(:put_rest).with("nodes/monkey", node).and_return("foo")
|
639
787
|
@rest.should_not_receive(:post_rest)
|
640
|
-
|
788
|
+
node.save
|
641
789
|
end
|
642
790
|
|
643
791
|
it "should create if it cannot update" do
|
644
|
-
|
792
|
+
node.name("monkey")
|
645
793
|
exception = mock("404 error", :code => "404")
|
646
794
|
@rest.should_receive(:put_rest).and_raise(Net::HTTPServerException.new("foo", exception))
|
647
|
-
@rest.should_receive(:post_rest).with("nodes",
|
648
|
-
|
795
|
+
@rest.should_receive(:post_rest).with("nodes", node)
|
796
|
+
node.save
|
649
797
|
end
|
650
798
|
|
651
799
|
describe "when whyrun mode is enabled" do
|
@@ -656,89 +804,13 @@ describe Chef::Node do
|
|
656
804
|
Chef::Config[:why_run] = false
|
657
805
|
end
|
658
806
|
it "should not save" do
|
659
|
-
|
807
|
+
node.name("monkey")
|
660
808
|
@rest.should_not_receive(:put_rest)
|
661
809
|
@rest.should_not_receive(:post_rest)
|
662
|
-
|
810
|
+
node.save
|
663
811
|
end
|
664
812
|
end
|
665
813
|
end
|
666
814
|
end
|
667
815
|
|
668
|
-
describe "acting as a CouchDB-backed model" do
|
669
|
-
before(:each) do
|
670
|
-
@couchdb = Chef::CouchDB.new
|
671
|
-
@mock_couch = mock('couch mock')
|
672
|
-
end
|
673
|
-
|
674
|
-
describe "list" do
|
675
|
-
before(:each) do
|
676
|
-
@mock_couch.stub!(:list).and_return(
|
677
|
-
{ "rows" => [ { "value" => "a", "key" => "avenue" } ] }
|
678
|
-
)
|
679
|
-
Chef::CouchDB.stub!(:new).and_return(@mock_couch)
|
680
|
-
end
|
681
|
-
|
682
|
-
it "should retrieve a list of nodes from CouchDB" do
|
683
|
-
Chef::Node.cdb_list.should eql(["avenue"])
|
684
|
-
end
|
685
|
-
|
686
|
-
it "should return just the ids if inflate is false" do
|
687
|
-
Chef::Node.cdb_list(false).should eql(["avenue"])
|
688
|
-
end
|
689
|
-
|
690
|
-
it "should return the full objects if inflate is true" do
|
691
|
-
Chef::Node.cdb_list(true).should eql(["a"])
|
692
|
-
end
|
693
|
-
end
|
694
|
-
|
695
|
-
describe "when loading a given node" do
|
696
|
-
it "should load a node from couchdb by name" do
|
697
|
-
@couchdb.should_receive(:load).with("node", "coffee").and_return(true)
|
698
|
-
Chef::CouchDB.stub!(:new).and_return(@couchdb)
|
699
|
-
Chef::Node.cdb_load("coffee")
|
700
|
-
end
|
701
|
-
end
|
702
|
-
|
703
|
-
describe "when destroying a Node" do
|
704
|
-
it "should delete this node from couchdb" do
|
705
|
-
@couchdb.should_receive(:delete).with("node", "bob", 1).and_return(true)
|
706
|
-
Chef::CouchDB.stub!(:new).and_return(@couchdb)
|
707
|
-
node = Chef::Node.new
|
708
|
-
node.name "bob"
|
709
|
-
node.couchdb_rev = 1
|
710
|
-
node.cdb_destroy
|
711
|
-
end
|
712
|
-
end
|
713
|
-
|
714
|
-
describe "when saving a Node" do
|
715
|
-
before(:each) do
|
716
|
-
@couchdb.stub!(:store).and_return({ "rev" => 33 })
|
717
|
-
Chef::CouchDB.stub!(:new).and_return(@couchdb)
|
718
|
-
@node = Chef::Node.new
|
719
|
-
@node.name "bob"
|
720
|
-
@node.couchdb_rev = 1
|
721
|
-
end
|
722
|
-
|
723
|
-
it "should save the node to couchdb" do
|
724
|
-
@couchdb.should_receive(:store).with("node", "bob", @node).and_return({ "rev" => 33 })
|
725
|
-
@node.cdb_save
|
726
|
-
end
|
727
|
-
|
728
|
-
it "should store the new couchdb_rev" do
|
729
|
-
@node.cdb_save
|
730
|
-
@node.couchdb_rev.should eql(33)
|
731
|
-
end
|
732
|
-
end
|
733
|
-
|
734
|
-
describe "create_design_document" do
|
735
|
-
it "should create our design document" do
|
736
|
-
@couchdb.should_receive(:create_design_document).with("nodes", Chef::Node::DESIGN_DOCUMENT)
|
737
|
-
Chef::CouchDB.stub!(:new).and_return(@couchdb)
|
738
|
-
Chef::Node.create_design_document
|
739
|
-
end
|
740
|
-
end
|
741
|
-
|
742
|
-
end
|
743
|
-
|
744
816
|
end
|