microwave 1.0.4 → 11.400.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/spec/unit/checksum_spec.rb
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Daniel DeLeo (<dan@opscode.com>)
|
3
|
-
# Copyright:: Copyright (c) 2010 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/checksum'
|
21
|
-
|
22
|
-
describe Chef::Checksum do
|
23
|
-
|
24
|
-
before do
|
25
|
-
Chef::Log.logger = Logger.new(StringIO.new)
|
26
|
-
|
27
|
-
@now = Time.now
|
28
|
-
|
29
|
-
Time.stub!(:now).and_return(@now)
|
30
|
-
|
31
|
-
@checksum_of_the_file = "3fafecfb15585ede6b840158cbc2f399"
|
32
|
-
@checksum = Chef::Checksum.new(@checksum_of_the_file)
|
33
|
-
end
|
34
|
-
|
35
|
-
it "has no original committed file location" do
|
36
|
-
@checksum.original_committed_file_location.should be_nil
|
37
|
-
end
|
38
|
-
|
39
|
-
it "has the MD5 checksum of the file it represents" do
|
40
|
-
@checksum.checksum.should == @checksum_of_the_file
|
41
|
-
end
|
42
|
-
|
43
|
-
it "stores the time it was created" do
|
44
|
-
@checksum.create_time.should == @now.iso8601
|
45
|
-
end
|
46
|
-
|
47
|
-
it "commits a sandbox file from a given location to the checksum repo location" do
|
48
|
-
@checksum.storage.should_receive(:commit).with("/tmp/arbitrary_file_location")
|
49
|
-
@checksum.should_receive(:cdb_save)
|
50
|
-
@checksum.commit_sandbox_file("/tmp/arbitrary_file_location")
|
51
|
-
@checksum.original_committed_file_location.should == "/tmp/arbitrary_file_location"
|
52
|
-
end
|
53
|
-
|
54
|
-
it "reverts committing a sandbox file" do
|
55
|
-
@checksum.storage.should_receive(:commit).with("/tmp/arbitrary_file_location")
|
56
|
-
@checksum.should_receive(:cdb_save)
|
57
|
-
@checksum.commit_sandbox_file("/tmp/arbitrary_file_location")
|
58
|
-
@checksum.original_committed_file_location.should == "/tmp/arbitrary_file_location"
|
59
|
-
|
60
|
-
@checksum.storage.should_receive(:revert).with("/tmp/arbitrary_file_location")
|
61
|
-
@checksum.should_receive(:cdb_destroy)
|
62
|
-
@checksum.revert_sandbox_file_commit
|
63
|
-
end
|
64
|
-
|
65
|
-
it "raises an error when trying to revert a checksum that was not previously committed" do
|
66
|
-
lambda {@checksum.revert_sandbox_file_commit}.should raise_error(Chef::Exceptions::IllegalChecksumRevert)
|
67
|
-
end
|
68
|
-
|
69
|
-
it "deletes the file and its document from couchdb" do
|
70
|
-
@checksum.should_receive(:cdb_destroy)
|
71
|
-
@checksum.storage.should_receive(:purge)
|
72
|
-
@checksum.purge
|
73
|
-
end
|
74
|
-
|
75
|
-
describe "when converted to json" do
|
76
|
-
before do
|
77
|
-
@checksum_as_json = @checksum.to_json
|
78
|
-
@checksum_as_hash_from_json = Chef::JSONCompat.from_json(@checksum_as_json, :create_additions => false)
|
79
|
-
end
|
80
|
-
|
81
|
-
it "contains the file's MD5 checksum" do
|
82
|
-
@checksum_as_hash_from_json["checksum"].should == @checksum_of_the_file
|
83
|
-
end
|
84
|
-
|
85
|
-
it "contains the creation time" do
|
86
|
-
@checksum_as_hash_from_json["create_time"].should == @now.iso8601
|
87
|
-
end
|
88
|
-
|
89
|
-
it "uses the file's MD5 checksum for its 'name' property" do
|
90
|
-
@checksum_as_hash_from_json["name"].should == @checksum_of_the_file
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
end
|
data/spec/unit/couchdb_spec.rb
DELETED
@@ -1,274 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Adam Jacob (<adam@opscode.com>)
|
3
|
-
# Copyright:: Copyright (c) 2008 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
|
-
|
21
|
-
describe Chef::CouchDB do
|
22
|
-
before(:each) do
|
23
|
-
Chef::Config[:couchdb_database] = "chef"
|
24
|
-
@rest = mock("Chef::REST")
|
25
|
-
@rest.stub!(:run_request).and_return({"couchdb" => "Welcome", "version" =>"0.9.0"})
|
26
|
-
@rest.stub!(:url).and_return("http://localhost:5984")
|
27
|
-
Chef::REST.stub!(:new).and_return(@rest)
|
28
|
-
@couchdb = Chef::CouchDB.new
|
29
|
-
end
|
30
|
-
|
31
|
-
describe "new" do
|
32
|
-
it "should create a new Chef::REST object from the default url" do
|
33
|
-
old_url = Chef::Config[:couchdb_url]
|
34
|
-
Chef::Config[:couchdb_url] = "http://monkey"
|
35
|
-
Chef::REST.should_receive(:new).with("http://monkey", nil, nil)
|
36
|
-
Chef::CouchDB.new
|
37
|
-
Chef::Config[:couchdb_url] = old_url
|
38
|
-
end
|
39
|
-
|
40
|
-
it "should create a new Chef::REST object from a provided url" do
|
41
|
-
Chef::REST.should_receive(:new).with("http://monkeypants", nil, nil)
|
42
|
-
Chef::CouchDB.new("http://monkeypants")
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
describe "create_db" do
|
47
|
-
before(:each) do
|
48
|
-
@couchdb.stub!(:create_design_document).and_return(true)
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should get a list of current databases" do
|
52
|
-
@rest.should_receive(:get_rest).and_return(["chef"])
|
53
|
-
@couchdb.create_db
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should create the chef database if it does not exist" do
|
57
|
-
@rest.stub!(:get_rest).and_return([])
|
58
|
-
@rest.should_receive(:put_rest).with("chef", {}).and_return(true)
|
59
|
-
@couchdb.create_db
|
60
|
-
end
|
61
|
-
|
62
|
-
it "should not create the chef database if it does exist" do
|
63
|
-
@rest.stub!(:get_rest).and_return(["chef"])
|
64
|
-
@rest.should_not_receive(:put_rest)
|
65
|
-
@couchdb.create_db
|
66
|
-
end
|
67
|
-
|
68
|
-
it "should return 'chef'" do
|
69
|
-
@rest.should_receive(:get_rest).with("_all_dbs").and_return(%w{chef})
|
70
|
-
@couchdb.create_db.should eql("chef")
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
describe "create_design_document" do
|
75
|
-
before(:each) do
|
76
|
-
@mock_design = {
|
77
|
-
"version" => 1,
|
78
|
-
"_rev" => 1
|
79
|
-
}
|
80
|
-
@mock_data = {
|
81
|
-
"version" => 1,
|
82
|
-
"language" => "javascript",
|
83
|
-
"views" => {
|
84
|
-
"all" => {
|
85
|
-
"map" => <<-EOJS
|
86
|
-
function(doc) {
|
87
|
-
if (doc.chef_type == "node") {
|
88
|
-
emit(doc.name, doc);
|
89
|
-
}
|
90
|
-
}
|
91
|
-
EOJS
|
92
|
-
},
|
93
|
-
}
|
94
|
-
}
|
95
|
-
@rest.stub!(:get_rest).and_return(@mock_design)
|
96
|
-
@rest.stub!(:put_rest).and_return(true)
|
97
|
-
@couchdb.stub!(:create_db).and_return(true)
|
98
|
-
end
|
99
|
-
|
100
|
-
def do_create_design_document
|
101
|
-
@couchdb.create_design_document("bob", @mock_data)
|
102
|
-
end
|
103
|
-
|
104
|
-
it "should fetch the existing design document" do
|
105
|
-
@rest.should_receive(:get_rest).with("chef/_design/bob")
|
106
|
-
do_create_design_document
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should populate the _rev in the new design if the versions dont match" do
|
110
|
-
@mock_data["version"] = 2
|
111
|
-
do_create_design_document
|
112
|
-
@mock_data["_rev"].should eql(1)
|
113
|
-
end
|
114
|
-
|
115
|
-
it "should create the view if it requires updating" do
|
116
|
-
@mock_data["version"] = 2
|
117
|
-
@rest.should_receive(:put_rest).with("chef/_design%2Fbob", @mock_data)
|
118
|
-
do_create_design_document
|
119
|
-
end
|
120
|
-
|
121
|
-
it "should not create the view if it does not require updating" do
|
122
|
-
@mock_data["version"] = 1
|
123
|
-
@rest.should_not_receive(:put_rest)
|
124
|
-
do_create_design_document
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
describe "store" do
|
129
|
-
before(:each) do
|
130
|
-
@mock_results = {
|
131
|
-
"rows" => [
|
132
|
-
"id" => 'a0934635-e111-45d9-8223-cb58e1c9434c'
|
133
|
-
]
|
134
|
-
}
|
135
|
-
@couchdb.stub!(:get_view).with("id_map", "name_to_id", :key => [ "node", "bob" ]).and_return(@mock_results)
|
136
|
-
end
|
137
|
-
|
138
|
-
it "should put the object into couchdb with a pre-existing GUID" do
|
139
|
-
item_to_store = {}
|
140
|
-
item_to_store.should_receive(:add_to_index)
|
141
|
-
@rest.should_receive(:put_rest).with("chef/#{@mock_results["rows"][0]["id"]}", item_to_store).and_return(true)
|
142
|
-
@couchdb.store("node", "bob", item_to_store)
|
143
|
-
end
|
144
|
-
|
145
|
-
it "should put the object into couchdb with a new GUID" do
|
146
|
-
@mock_results = { "rows" => [] }
|
147
|
-
item_to_store = {}
|
148
|
-
item_to_store.should_receive(:add_to_index).with(:database => "chef", :id => "aaaaaaaa-xxxx-xxxx-xxxx-xxxxxxxxxxx", :type => "node")
|
149
|
-
@couchdb.stub!(:get_view).with("id_map", "name_to_id", :key => [ "node", "bob" ]).and_return(@mock_results)
|
150
|
-
UUIDTools::UUID.stub!(:random_create).and_return("aaaaaaaa-xxxx-xxxx-xxxx-xxxxxxxxxxx")
|
151
|
-
@rest.should_receive(:put_rest).with("chef/aaaaaaaa-xxxx-xxxx-xxxx-xxxxxxxxxxx", item_to_store).and_return(true)
|
152
|
-
@couchdb.store("node", "bob", item_to_store)
|
153
|
-
end
|
154
|
-
|
155
|
-
end
|
156
|
-
|
157
|
-
describe "when fetching the database status" do
|
158
|
-
it "gets couchdb's version string'" do
|
159
|
-
@rest.should_receive(:get_rest).with('/').and_return({"couchdb" => "Welcome","version" => "1.0.1"})
|
160
|
-
@couchdb.server_stats.should == {"couchdb" => "Welcome","version" => "1.0.1"}
|
161
|
-
end
|
162
|
-
|
163
|
-
it "gets database stats" do
|
164
|
-
db_stats = {"db_name" => "opscode_account","doc_count" => 206,"doc_del_count" => 1,"update_seq" => 208,"purge_seq" => 0,
|
165
|
-
"compact_running" => false,"disk_size" => 122969,"instance_start_time" => "1298070021394804","disk_format_version" => 5,"committed_update_seq" => 208}
|
166
|
-
@rest.should_receive(:get_rest).with('/chef').and_return(db_stats)
|
167
|
-
@couchdb.db_stats.should == db_stats
|
168
|
-
end
|
169
|
-
|
170
|
-
end
|
171
|
-
|
172
|
-
describe "load" do
|
173
|
-
before(:each) do
|
174
|
-
@mock_node = Chef::Node.new()
|
175
|
-
@mock_node.name("bob")
|
176
|
-
@couchdb.stub!(:find_by_name).with("node", "bob").and_return(@mock_node)
|
177
|
-
end
|
178
|
-
|
179
|
-
it "should load the object from couchdb" do
|
180
|
-
@couchdb.load("node", "bob").should eql(@mock_node)
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
describe "delete" do
|
185
|
-
before(:each) do
|
186
|
-
@mock_current = {
|
187
|
-
"version" => 1,
|
188
|
-
"_rev" => 1
|
189
|
-
}
|
190
|
-
@rest.stub!(:get_rest).and_return(@mock_current)
|
191
|
-
@rest.stub!(:delete_rest).and_return(true)
|
192
|
-
@node = Chef::Node.new()
|
193
|
-
@node.name("bob")
|
194
|
-
@node.couchdb_rev = 15
|
195
|
-
@couchdb.stub!(:find_by_name).with("node", "bob", true).and_return([ @node, "ax" ])
|
196
|
-
end
|
197
|
-
|
198
|
-
def do_delete(rev=nil)
|
199
|
-
@couchdb.delete("node", "bob", rev)
|
200
|
-
end
|
201
|
-
|
202
|
-
it "should remove the object from couchdb with a specific revision" do
|
203
|
-
@node.should_receive(:delete_from_index)
|
204
|
-
@rest.should_receive(:delete_rest).with("chef/ax?rev=1")
|
205
|
-
do_delete(1)
|
206
|
-
end
|
207
|
-
|
208
|
-
it "should remove the object from couchdb based on the couchdb_rev of the current obj" do
|
209
|
-
@node.should_receive(:delete_from_index)
|
210
|
-
@rest.should_receive(:delete_rest).with("chef/ax?rev=15")
|
211
|
-
do_delete
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
describe "list" do
|
216
|
-
before(:each) do
|
217
|
-
Chef::Config.stub!(:[]).with(:couchdb_database).and_return("chef")
|
218
|
-
@mock_response = {"rows" => []}
|
219
|
-
end
|
220
|
-
|
221
|
-
describe "on couchdb 0.9+" do
|
222
|
-
before do
|
223
|
-
Chef::Config.stub!(:[]).with(:couchdb_version).and_return(0.9)
|
224
|
-
end
|
225
|
-
|
226
|
-
it "should get the view for all objects if inflate is true" do
|
227
|
-
@rest.should_receive(:get_rest).with("chef/_design/node/_view/all").and_return(@mock_response)
|
228
|
-
@couchdb.list("node", true)
|
229
|
-
end
|
230
|
-
|
231
|
-
it "should get the view for just the object id's if inflate is false" do
|
232
|
-
@rest.should_receive(:get_rest).with("chef/_design/node/_view/all_id").and_return(@mock_response)
|
233
|
-
@couchdb.list("node", false)
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
describe "has_key?" do
|
239
|
-
it "should return true if the object exists" do
|
240
|
-
@couchdb.stub!(:find_by_name).with("node", "bob").and_return(true)
|
241
|
-
@couchdb.has_key?("node", "bob").should eql(true)
|
242
|
-
end
|
243
|
-
|
244
|
-
it "should return false if the object does not exist" do
|
245
|
-
@couchdb.stub!(:find_by_name).and_raise(Chef::Exceptions::CouchDBNotFound)
|
246
|
-
@couchdb.has_key?("node", "bob").should eql(false)
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
describe "get_view" do
|
251
|
-
it "should construct a call to the view for the proper design document" do
|
252
|
-
@rest.should_receive(:get_rest).with("chef/_design/nodes/_view/mastodon")
|
253
|
-
@couchdb.get_view("nodes", "mastodon")
|
254
|
-
end
|
255
|
-
|
256
|
-
it "should allow arguments to the view" do
|
257
|
-
@rest.should_receive(:get_rest).with("chef/_design/nodes/_view/mastodon?startkey=%22dont%20stay%22")
|
258
|
-
@couchdb.get_view("nodes", "mastodon", :startkey => "dont stay")
|
259
|
-
end
|
260
|
-
|
261
|
-
end
|
262
|
-
|
263
|
-
describe "view_uri" do
|
264
|
-
it "should output an appropriately formed view URI" do
|
265
|
-
@couchdb.should_receive(:view_uri).with("nodes", "all").and_return("chef/_design/nodes/_view/all")
|
266
|
-
@couchdb.view_uri("nodes", "all")
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
end
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
@@ -1,391 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Daniel DeLeo (<dan@kallistec.com>)
|
3
|
-
# Copyright:: Copyright (c) 2009 Daniel DeLeo
|
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
|
-
|
21
|
-
class Chef
|
22
|
-
class IndexableTestHarness
|
23
|
-
include Chef::IndexQueue::Indexable
|
24
|
-
attr_reader :couchdb_id
|
25
|
-
def couchdb_id=(value)
|
26
|
-
self.index_id = @couchdb_id = value
|
27
|
-
end
|
28
|
-
attr_reader :index_id
|
29
|
-
def index_id=(value)
|
30
|
-
@index_id = value
|
31
|
-
end
|
32
|
-
|
33
|
-
def to_hash
|
34
|
-
{"ohai_world" => "I am IndexableTestHarness", "object_id" => object_id}
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class IndexQueueSpecError < RuntimeError ; end
|
41
|
-
|
42
|
-
class FauxQueue
|
43
|
-
|
44
|
-
attr_reader :published_message, :publish_options
|
45
|
-
|
46
|
-
# Note: If publish is not called, this published_message will cause
|
47
|
-
# JSON parsing to die with "can't convert Symbol into String"
|
48
|
-
def initialize
|
49
|
-
@published_message = :epic_fail!
|
50
|
-
@publish_options = :epic_fail!
|
51
|
-
end
|
52
|
-
|
53
|
-
def publish(message, options=nil)
|
54
|
-
@published_message = message
|
55
|
-
@publish_options = options
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
class IndexConsumerTestHarness
|
60
|
-
include Chef::IndexQueue::Consumer
|
61
|
-
|
62
|
-
attr_reader :last_indexed_object, :unexposed_attr
|
63
|
-
|
64
|
-
expose :index_this
|
65
|
-
|
66
|
-
def index_this(object_to_index)
|
67
|
-
@last_indexed_object = object_to_index
|
68
|
-
end
|
69
|
-
|
70
|
-
def not_exposed(arg)
|
71
|
-
@unexposed_attr = arg
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
describe Chef::IndexQueue::Indexable do
|
76
|
-
def a_uuid
|
77
|
-
/[0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{12}/
|
78
|
-
end
|
79
|
-
|
80
|
-
before do
|
81
|
-
Chef::IndexableTestHarness.reset_index_metadata!
|
82
|
-
@publisher = Chef::IndexQueue::AmqpClient.instance
|
83
|
-
@indexable_obj = Chef::IndexableTestHarness.new
|
84
|
-
@item_as_hash = {"ohai_world" => "I am IndexableTestHarness", "object_id" => @indexable_obj.object_id}
|
85
|
-
|
86
|
-
@now = Time.now
|
87
|
-
Time.stub!(:now).and_return(@now)
|
88
|
-
end
|
89
|
-
|
90
|
-
it "downcases the class name for the index_object_type when it's not explicitly set" do
|
91
|
-
@indexable_obj.index_object_type.should == "indexable_test_harness"
|
92
|
-
end
|
93
|
-
|
94
|
-
it "uses an explicitly set index_object_type" do
|
95
|
-
Chef::IndexableTestHarness.index_object_type :a_weird_name
|
96
|
-
@indexable_obj.index_object_type.should == "a_weird_name"
|
97
|
-
end
|
98
|
-
|
99
|
-
it "adds 'database', 'type', and 'id' (UUID) keys to the published object" do
|
100
|
-
with_metadata = @indexable_obj.with_indexer_metadata(:database => "foo", :id=>UUIDTools::UUID.random_create.to_s)
|
101
|
-
with_metadata.should have(5).keys
|
102
|
-
with_metadata.keys.should include("type", "id", "item", "database", "enqueued_at")
|
103
|
-
with_metadata["type"].should == "indexable_test_harness"
|
104
|
-
with_metadata["database"].should == "foo"
|
105
|
-
with_metadata["item"].should == @item_as_hash
|
106
|
-
with_metadata["id"].should match(a_uuid)
|
107
|
-
with_metadata["enqueued_at"].should == @now.utc.to_i
|
108
|
-
end
|
109
|
-
|
110
|
-
it "uses the couchdb_id if available" do
|
111
|
-
expected_uuid = "0000000-1111-2222-3333-444444444444"
|
112
|
-
@indexable_obj.couchdb_id = expected_uuid
|
113
|
-
metadata_id = @indexable_obj.with_indexer_metadata["id"]
|
114
|
-
metadata_id.should == expected_uuid
|
115
|
-
end
|
116
|
-
|
117
|
-
describe "adds and removes items to and from the index and respects Chef::Config[:persistent_queue]" do
|
118
|
-
before do
|
119
|
-
@exchange = mock("Bunny::Exchange")
|
120
|
-
@amqp_client = mock("Bunny::Client", :start => true, :exchange => @exchange)
|
121
|
-
@publisher.stub!(:amqp_client).and_return(@amqp_client)
|
122
|
-
@queue = FauxQueue.new
|
123
|
-
@publisher.should_receive(:queue_for_object).with("0000000-1111-2222-3333-444444444444").and_yield(@queue)
|
124
|
-
Chef::Config[:persistent_queue] = false
|
125
|
-
end
|
126
|
-
|
127
|
-
it "adds items to the index" do
|
128
|
-
@amqp_client.should_not_receive(:tx_select)
|
129
|
-
@amqp_client.should_not_receive(:tx_commit)
|
130
|
-
@amqp_client.should_not_receive(:tx_rollback)
|
131
|
-
|
132
|
-
@indexable_obj.add_to_index(:database => "couchdb@localhost,etc.", :id=>"0000000-1111-2222-3333-444444444444")
|
133
|
-
|
134
|
-
published_message = Chef::JSONCompat.from_json(@queue.published_message)
|
135
|
-
published_message.should == {"action" => "add", "payload" => {"item" => @item_as_hash,
|
136
|
-
"type" => "indexable_test_harness",
|
137
|
-
"database" => "couchdb@localhost,etc.",
|
138
|
-
"id" => "0000000-1111-2222-3333-444444444444",
|
139
|
-
"enqueued_at" => @now.utc.to_i}}
|
140
|
-
@queue.publish_options[:persistent].should == false
|
141
|
-
end
|
142
|
-
|
143
|
-
it "adds items to the index transactionactionally when Chef::Config[:persistent_queue] == true" do
|
144
|
-
@amqp_client.should_receive(:tx_select)
|
145
|
-
@amqp_client.should_receive(:tx_commit)
|
146
|
-
@amqp_client.should_not_receive(:tx_rollback)
|
147
|
-
|
148
|
-
# set and restore Chef::Config[:persistent_queue] to true
|
149
|
-
orig_value = Chef::Config[:persistent_queue]
|
150
|
-
Chef::Config[:persistent_queue] = true
|
151
|
-
begin
|
152
|
-
@indexable_obj.add_to_index(:database => "couchdb@localhost,etc.", :id=>"0000000-1111-2222-3333-444444444444")
|
153
|
-
ensure
|
154
|
-
Chef::Config[:persistent_queue] = orig_value
|
155
|
-
end
|
156
|
-
|
157
|
-
published_message = Chef::JSONCompat.from_json(@queue.published_message)
|
158
|
-
published_message.should == {"action" => "add", "payload" => {"item" => @item_as_hash,
|
159
|
-
"type" => "indexable_test_harness",
|
160
|
-
"database" => "couchdb@localhost,etc.",
|
161
|
-
"id" => "0000000-1111-2222-3333-444444444444",
|
162
|
-
"enqueued_at" => @now.utc.to_i}}
|
163
|
-
@queue.publish_options[:persistent].should == true
|
164
|
-
end
|
165
|
-
|
166
|
-
it "adds items to the index transactionally when Chef::Config[:persistent_queue] == true and rolls it back when there is a failure" do
|
167
|
-
@amqp_client.should_receive(:tx_select)
|
168
|
-
@amqp_client.should_receive(:tx_rollback)
|
169
|
-
@amqp_client.should_not_receive(:tx_commit)
|
170
|
-
|
171
|
-
# cause the publish to fail, and make sure the failure is our own
|
172
|
-
# by using a specific class
|
173
|
-
@queue.should_receive(:publish).and_raise(IndexQueueSpecError)
|
174
|
-
|
175
|
-
# set and restore Chef::Config[:persistent_queue] to true
|
176
|
-
orig_value = Chef::Config[:persistent_queue]
|
177
|
-
Chef::Config[:persistent_queue] = true
|
178
|
-
begin
|
179
|
-
lambda{
|
180
|
-
@indexable_obj.add_to_index(:database => "couchdb@localhost,etc.", :id=>"0000000-1111-2222-3333-444444444444")
|
181
|
-
}.should raise_error(IndexQueueSpecError)
|
182
|
-
ensure
|
183
|
-
Chef::Config[:persistent_queue] = orig_value
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
it "removes items from the index" do
|
188
|
-
@amqp_client.should_not_receive(:tx_select)
|
189
|
-
@amqp_client.should_not_receive(:tx_commit)
|
190
|
-
@amqp_client.should_not_receive(:tx_rollback)
|
191
|
-
|
192
|
-
@indexable_obj.delete_from_index(:database => "couchdb2@localhost", :id=>"0000000-1111-2222-3333-444444444444")
|
193
|
-
published_message = Chef::JSONCompat.from_json(@queue.published_message)
|
194
|
-
published_message.should == {"action" => "delete", "payload" => { "item" => @item_as_hash,
|
195
|
-
"type" => "indexable_test_harness",
|
196
|
-
"database" => "couchdb2@localhost",
|
197
|
-
"id" => "0000000-1111-2222-3333-444444444444",
|
198
|
-
"enqueued_at" => @now.utc.to_i}}
|
199
|
-
@queue.publish_options[:persistent].should == false
|
200
|
-
end
|
201
|
-
|
202
|
-
it "removes items from the index transactionactionally when Chef::Config[:persistent_queue] == true" do
|
203
|
-
@amqp_client.should_receive(:tx_select)
|
204
|
-
@amqp_client.should_receive(:tx_commit)
|
205
|
-
@amqp_client.should_not_receive(:tx_rollback)
|
206
|
-
|
207
|
-
# set and restore Chef::Config[:persistent_queue] to true
|
208
|
-
orig_value = Chef::Config[:persistent_queue]
|
209
|
-
Chef::Config[:persistent_queue] = true
|
210
|
-
begin
|
211
|
-
@indexable_obj.delete_from_index(:database => "couchdb2@localhost", :id=>"0000000-1111-2222-3333-444444444444")
|
212
|
-
ensure
|
213
|
-
Chef::Config[:persistent_queue] = orig_value
|
214
|
-
end
|
215
|
-
|
216
|
-
published_message = Chef::JSONCompat.from_json(@queue.published_message)
|
217
|
-
published_message.should == {"action" => "delete", "payload" => { "item" => @item_as_hash,
|
218
|
-
"type" => "indexable_test_harness",
|
219
|
-
"database" => "couchdb2@localhost",
|
220
|
-
"id" => "0000000-1111-2222-3333-444444444444",
|
221
|
-
"enqueued_at" => @now.utc.to_i}}
|
222
|
-
@queue.publish_options[:persistent].should == true
|
223
|
-
end
|
224
|
-
|
225
|
-
it "remove items from the index transactionally when Chef::Config[:persistent_queue] == true and rolls it back when there is a failure" do
|
226
|
-
@amqp_client.should_receive(:tx_select)
|
227
|
-
@amqp_client.should_receive(:tx_rollback)
|
228
|
-
@amqp_client.should_not_receive(:tx_commit)
|
229
|
-
|
230
|
-
# cause the publish to fail, and make sure the failure is our own
|
231
|
-
# by using a specific class
|
232
|
-
@queue.should_receive(:publish).and_raise(IndexQueueSpecError)
|
233
|
-
|
234
|
-
# set and restore Chef::Config[:persistent_queue] to true
|
235
|
-
orig_value = Chef::Config[:persistent_queue]
|
236
|
-
Chef::Config[:persistent_queue] = true
|
237
|
-
begin
|
238
|
-
lambda{
|
239
|
-
@indexable_obj.delete_from_index(:database => "couchdb2@localhost", :id=>"0000000-1111-2222-3333-444444444444") }.should raise_error(IndexQueueSpecError)
|
240
|
-
ensure
|
241
|
-
Chef::Config[:persistent_queue] = orig_value
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
end
|
247
|
-
|
248
|
-
describe Chef::IndexQueue::Consumer do
|
249
|
-
before do
|
250
|
-
@amqp_client = Chef::IndexQueue::AmqpClient.instance
|
251
|
-
@consumer = IndexConsumerTestHarness.new
|
252
|
-
end
|
253
|
-
|
254
|
-
it "keeps a whitelist of exposed methods" do
|
255
|
-
IndexConsumerTestHarness.exposed_methods.should == [:index_this]
|
256
|
-
IndexConsumerTestHarness.whitelisted?(:index_this).should be_true
|
257
|
-
IndexConsumerTestHarness.whitelisted?(:not_exposed).should be_false
|
258
|
-
end
|
259
|
-
|
260
|
-
it "doesn't route non-whitelisted methods" do
|
261
|
-
payload_json = {"payload" => {"a_placeholder" => "object"}, "action" => "not_exposed"}.to_json
|
262
|
-
received_message = {:payload => payload_json}
|
263
|
-
lambda {@consumer.call_action_for_message(received_message)}.should raise_error(ArgumentError)
|
264
|
-
@consumer.unexposed_attr.should be_nil
|
265
|
-
end
|
266
|
-
|
267
|
-
it "routes message payloads to the correct method" do
|
268
|
-
payload_json = {"payload" => {"a_placeholder" => "object"}, "action" => "index_this"}.to_json
|
269
|
-
received_message = {:payload => payload_json}
|
270
|
-
@consumer.call_action_for_message(received_message)
|
271
|
-
@consumer.last_indexed_object.should == {"a_placeholder" => "object"}
|
272
|
-
|
273
|
-
end
|
274
|
-
|
275
|
-
it "subscribes to the queue for the indexer" do
|
276
|
-
payload_json = {"payload" => {"a_placeholder" => "object"}, "action" => "index_this"}.to_json
|
277
|
-
message = {:payload => payload_json}
|
278
|
-
queue = mock("Bunny::Queue")
|
279
|
-
@amqp_client.stub!(:queue).and_return(queue)
|
280
|
-
queue.should_receive(:subscribe).with(:timeout => false, :ack => true).and_yield(message)
|
281
|
-
@consumer.run
|
282
|
-
@consumer.last_indexed_object.should == {"a_placeholder" => "object"}
|
283
|
-
end
|
284
|
-
|
285
|
-
end
|
286
|
-
|
287
|
-
|
288
|
-
describe Chef::IndexQueue::AmqpClient do
|
289
|
-
before do
|
290
|
-
Chef::Config[:amqp_host] = '4.3.2.1'
|
291
|
-
Chef::Config[:amqp_port] = '1337'
|
292
|
-
Chef::Config[:amqp_user] = 'teh_rspecz'
|
293
|
-
Chef::Config[:amqp_pass] = 'access_granted2rspec'
|
294
|
-
Chef::Config[:amqp_vhost] = '/chef-specz'
|
295
|
-
Chef::Config[:amqp_consumer_id] = nil
|
296
|
-
|
297
|
-
@publisher = Chef::IndexQueue::AmqpClient.instance
|
298
|
-
@exchange = mock("Bunny::Exchange")
|
299
|
-
|
300
|
-
@amqp_client = mock("Bunny::Client", :start => true, :exchange => @exchange)
|
301
|
-
def @amqp_client.connected?; false; end # stubbing predicate methods not working?
|
302
|
-
Bunny.stub!(:new).and_return(@amqp_client)
|
303
|
-
|
304
|
-
@publisher.reset!
|
305
|
-
end
|
306
|
-
|
307
|
-
after do
|
308
|
-
@publisher.disconnected!
|
309
|
-
end
|
310
|
-
|
311
|
-
it "is a singleton" do
|
312
|
-
lambda {Chef::IndexQueue::Indexable::AmqpClient.new}.should raise_error
|
313
|
-
end
|
314
|
-
|
315
|
-
it "creates an amqp client object on demand, starts a connection, and caches it" do
|
316
|
-
@amqp_client.should_receive(:start).once
|
317
|
-
@amqp_client.should_receive(:qos).with(:prefetch_count => 1)
|
318
|
-
::Bunny.should_receive(:new).once.and_return(@amqp_client)
|
319
|
-
@publisher.amqp_client.should == @amqp_client
|
320
|
-
@publisher.amqp_client
|
321
|
-
end
|
322
|
-
|
323
|
-
it "configures the amqp client with credentials from the config file" do
|
324
|
-
@publisher.reset!
|
325
|
-
Bunny.should_receive(:new).with(:spec => '08', :host => '4.3.2.1', :port => '1337', :user => "teh_rspecz",
|
326
|
-
:pass => "access_granted2rspec", :vhost => '/chef-specz').and_return(@amqp_client)
|
327
|
-
@amqp_client.should_receive(:qos).with(:prefetch_count => 1)
|
328
|
-
@publisher.amqp_client.should == @amqp_client
|
329
|
-
end
|
330
|
-
|
331
|
-
it "creates an amqp exchange on demand and caches it" do
|
332
|
-
@amqp_client.stub!(:qos)
|
333
|
-
@publisher.exchange.should == @exchange
|
334
|
-
@amqp_client.should_not_receive(:exchange)
|
335
|
-
@publisher.exchange.should == @exchange
|
336
|
-
end
|
337
|
-
|
338
|
-
describe "publishing" do
|
339
|
-
|
340
|
-
before do
|
341
|
-
@queue_1 = FauxQueue.new
|
342
|
-
@queue_2 = FauxQueue.new
|
343
|
-
|
344
|
-
@amqp_client.stub!(:qos)
|
345
|
-
#@amqp_client.stub!(:queue).and_return(@queue)
|
346
|
-
@data = {"some_data" => "in_a_hash"}
|
347
|
-
end
|
348
|
-
|
349
|
-
it "resets the client upon a Bunny::ServerDownError when publishing" do
|
350
|
-
Bunny.stub!(:new).and_return(@amqp_client)
|
351
|
-
@amqp_client.should_receive(:queue).with("vnode-68", {:passive=>false, :durable=>true, :exclusive=>false, :auto_delete=>false}).twice.and_return(@queue_1, @queue_2)
|
352
|
-
|
353
|
-
@queue_1.should_receive(:publish).with(@data).and_raise(Bunny::ServerDownError)
|
354
|
-
@queue_2.should_receive(:publish).with(@data).and_raise(Bunny::ServerDownError)
|
355
|
-
|
356
|
-
@publisher.should_receive(:disconnected!).at_least(3).times
|
357
|
-
lambda {@publisher.queue_for_object("00000000-1111-2222-3333-444444444444") {|q| q.publish(@data)}}.should raise_error(Bunny::ServerDownError)
|
358
|
-
end
|
359
|
-
|
360
|
-
it "resets the client upon a Bunny::ConnectionError when publishing" do
|
361
|
-
Bunny.stub!(:new).and_return(@amqp_client)
|
362
|
-
@amqp_client.should_receive(:queue).with("vnode-68", {:passive=>false, :durable=>true, :exclusive=>false, :auto_delete=>false}).twice.and_return(@queue_1, @queue_2)
|
363
|
-
|
364
|
-
@queue_1.should_receive(:publish).with(@data).and_raise(Bunny::ConnectionError)
|
365
|
-
@queue_2.should_receive(:publish).with(@data).and_raise(Bunny::ConnectionError)
|
366
|
-
|
367
|
-
@publisher.should_receive(:disconnected!).at_least(3).times
|
368
|
-
lambda {@publisher.queue_for_object("00000000-1111-2222-3333-444444444444") {|q| q.publish(@data)}}.should raise_error(Bunny::ConnectionError)
|
369
|
-
end
|
370
|
-
|
371
|
-
it "resets the client upon a Errno::ECONNRESET when publishing" do
|
372
|
-
Bunny.stub!(:new).and_return(@amqp_client)
|
373
|
-
@amqp_client.should_receive(:queue).with("vnode-68", {:passive=>false, :durable=>true, :exclusive=>false, :auto_delete=>false}).twice.and_return(@queue_1, @queue_2)
|
374
|
-
|
375
|
-
@queue_1.should_receive(:publish).with(@data).and_raise(Errno::ECONNRESET)
|
376
|
-
@queue_2.should_receive(:publish).with(@data).and_raise(Errno::ECONNRESET)
|
377
|
-
|
378
|
-
@publisher.should_receive(:disconnected!).at_least(3).times
|
379
|
-
lambda {@publisher.queue_for_object("00000000-1111-2222-3333-444444444444") {|q| q.publish(@data)}}.should raise_error(Errno::ECONNRESET)
|
380
|
-
end
|
381
|
-
|
382
|
-
end
|
383
|
-
|
384
|
-
it "stops bunny and clears subscriptions" do
|
385
|
-
bunny_client = mock("Bunny::Client")
|
386
|
-
@publisher.instance_variable_set(:@amqp_client, bunny_client)
|
387
|
-
bunny_client.should_receive(:stop)
|
388
|
-
@publisher.stop
|
389
|
-
end
|
390
|
-
|
391
|
-
end
|