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
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
|