chef-solr 0.9.18 → 0.10.0.beta.0
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/bin/{chef-solr-indexer → chef-solr-installer} +4 -7
- data/lib/chef/solr.rb +1 -234
- data/lib/chef/solr/application/solr.rb +71 -43
- data/lib/chef/solr/solr_installer.rb +385 -0
- data/lib/chef/solr/version.rb +7 -1
- data/solr/solr-home.tar.gz +0 -0
- data/solr/solr-jetty.tar.gz +0 -0
- metadata +11 -41
- data/lib/chef/solr/application/indexer.rb +0 -148
- data/lib/chef/solr/index.rb +0 -103
- data/lib/chef/solr/index_queue_consumer.rb +0 -82
- data/lib/chef/solr/query.rb +0 -99
- data/spec/chef/solr/index_spec.rb +0 -187
- data/spec/chef/solr/query_spec.rb +0 -14
- data/spec/chef/solr_spec.rb +0 -301
- data/spec/spec.opts +0 -1
- data/spec/spec_helper.rb +0 -14
data/lib/chef/solr/query.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Adam Jacob (<adam@opscode.com>)
|
3
|
-
# Author:: Nuo Yan (<nuo@opscode.com>)
|
4
|
-
# Copyright:: Copyright (c) 2010 Opscode, Inc.
|
5
|
-
# License:: Apache License, Version 2.0
|
6
|
-
#
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
-
# you may not use this file except in compliance with the License.
|
9
|
-
# You may obtain a copy of the License at
|
10
|
-
#
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
-
#
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
-
# See the License for the specific language governing permissions and
|
17
|
-
# limitations under the License.
|
18
|
-
#
|
19
|
-
|
20
|
-
require 'chef/couchdb'
|
21
|
-
require 'chef/node'
|
22
|
-
require 'chef/role'
|
23
|
-
require 'chef/data_bag'
|
24
|
-
require 'chef/data_bag_item'
|
25
|
-
require 'chef/solr'
|
26
|
-
require 'chef/log'
|
27
|
-
require 'chef/config'
|
28
|
-
|
29
|
-
class Chef
|
30
|
-
class Solr
|
31
|
-
class Query < Chef::Solr
|
32
|
-
|
33
|
-
# Create a new Query object - takes the solr_url and optional
|
34
|
-
# Chef::CouchDB object to inflate objects into.
|
35
|
-
def initialize(solr_url=Chef::Config[:solr_url], couchdb = nil)
|
36
|
-
super(solr_url)
|
37
|
-
if couchdb.nil?
|
38
|
-
@database = Chef::Config[:couchdb_database]
|
39
|
-
@couchdb = Chef::CouchDB.new(nil, Chef::Config[:couchdb_database])
|
40
|
-
else
|
41
|
-
unless couchdb.kind_of?(Chef::CouchDB)
|
42
|
-
Chef::Log.warn("Passing the database name to Chef::Solr::Query initialization is deprecated. Please pass in the Chef::CouchDB object instead.")
|
43
|
-
@database = couchdb
|
44
|
-
@couchdb = Chef::CouchDB.new(nil, couchdb)
|
45
|
-
else
|
46
|
-
@database = couchdb.couchdb_database
|
47
|
-
@couchdb = couchdb
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# A raw query against CouchDB - takes the type of object to find, and raw
|
53
|
-
# Solr options.
|
54
|
-
#
|
55
|
-
# You'll wind up having to page things yourself.
|
56
|
-
def raw(type, options={})
|
57
|
-
qtype = case type
|
58
|
-
when "role",:role,"node",:node,"client",:client
|
59
|
-
type
|
60
|
-
else
|
61
|
-
[ "data_bag_item", type ]
|
62
|
-
end
|
63
|
-
results = solr_select(@database, qtype, options)
|
64
|
-
Chef::Log.debug("Searching #{@database} #{qtype.inspect} for #{options.inspect} with results:\n#{results.inspect}")
|
65
|
-
objects = if results["response"]["docs"].length > 0
|
66
|
-
bulk_objects = @couchdb.bulk_get( results["response"]["docs"].collect { |d| d["X_CHEF_id_CHEF_X"] } )
|
67
|
-
Chef::Log.debug("bulk get of objects: #{bulk_objects.inspect}")
|
68
|
-
bulk_objects
|
69
|
-
else
|
70
|
-
[]
|
71
|
-
end
|
72
|
-
[ objects, results["response"]["start"], results["response"]["numFound"], results["responseHeader"] ]
|
73
|
-
end
|
74
|
-
|
75
|
-
# Search Solr for objects of a given type, for a given query. If you give
|
76
|
-
# it a block, it will handle the paging for you dynamically.
|
77
|
-
def search(type, query="*:*", sort='X_CHEF_id_CHEF_X asc', start=0, rows=1000, &block)
|
78
|
-
options = {
|
79
|
-
:q => query,
|
80
|
-
:start => start,
|
81
|
-
:rows => rows
|
82
|
-
}
|
83
|
-
options[:sort] = sort if sort && ! sort.empty?
|
84
|
-
objects, start, total, response_header = raw(type, options)
|
85
|
-
if block
|
86
|
-
objects.each { |o| block.call(o) }
|
87
|
-
unless (start + objects.length) >= total
|
88
|
-
nstart = start + rows
|
89
|
-
search(type, query, sort, nstart, rows, &block)
|
90
|
-
end
|
91
|
-
true
|
92
|
-
else
|
93
|
-
[ objects, start, total ]
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
@@ -1,187 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join("#{File.dirname(__FILE__)}", '..', '..', 'spec_helper'))
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
describe Chef::Solr::Index do
|
6
|
-
before(:each) do
|
7
|
-
@index = Chef::Solr::Index.new
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "initialize" do
|
11
|
-
it "should return a Chef::Solr::Index" do
|
12
|
-
@index.should be_a_kind_of(Chef::Solr::Index)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
describe "add" do
|
17
|
-
before(:each) do
|
18
|
-
@index.stub!(:solr_add).and_return(true)
|
19
|
-
@index.stub!(:solr_commit).and_return(true)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should take an object that responds to .keys as it's argument" do
|
23
|
-
lambda { @index.add(1, "chef_opscode", "node", { :one => :two }) }.should_not raise_error(ArgumentError)
|
24
|
-
lambda { @index.add(1, "chef_opscode", "node", "SOUP") }.should raise_error(ArgumentError)
|
25
|
-
lambda { @index.add(2, "chef_opscode", "node", mock("Foo", :keys => true)) }.should_not raise_error(ArgumentError)
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should index the object as a single flat hash, with only strings or arrays as values" do
|
29
|
-
validate = {
|
30
|
-
"X_CHEF_id_CHEF_X" => [1],
|
31
|
-
"X_CHEF_database_CHEF_X" => ["monkey"],
|
32
|
-
"X_CHEF_type_CHEF_X" => ["snakes"],
|
33
|
-
"foo" => ["bar"],
|
34
|
-
"battles" => [ "often", "but", "for" ],
|
35
|
-
"battles_often" => ["sings like smurfs"],
|
36
|
-
"often" => ["sings like smurfs"],
|
37
|
-
"battles_but" => ["still has good records"],
|
38
|
-
"but" => ["still has good records"],
|
39
|
-
"battles_for" => [ "all", "of", "that" ],
|
40
|
-
"for" => [ "all", "of", "that" ],
|
41
|
-
"snoopy" => ["sits-in-a-barn"],
|
42
|
-
"battles_X" => [ "sings like smurfs", "still has good records", "all", "of", "that" ],
|
43
|
-
"X_often" =>[ "sings like smurfs"],
|
44
|
-
"X_but" => ["still has good records"],
|
45
|
-
"X_for" => [ "all", "of", "that" ]
|
46
|
-
}
|
47
|
-
to_index = @index.add(1, "monkey", "snakes", {
|
48
|
-
"foo" => :bar,
|
49
|
-
"battles" => {
|
50
|
-
"often" => "sings like smurfs",
|
51
|
-
"but" => "still has good records",
|
52
|
-
"for" => [ "all", "of", "that" ]
|
53
|
-
},
|
54
|
-
"snoopy" => "sits-in-a-barn"
|
55
|
-
})
|
56
|
-
|
57
|
-
validate.each do |k, v|
|
58
|
-
if v.kind_of?(Array)
|
59
|
-
to_index[k].sort.should == v.sort
|
60
|
-
else
|
61
|
-
to_index[k].should == v
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
it "should send the document to solr" do
|
67
|
-
@index.should_receive(:solr_add)
|
68
|
-
@index.add(1, "monkey", "snakes", { "foo" => "bar" })
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe "delete" do
|
73
|
-
it "should delete by id" do
|
74
|
-
@index.should_receive(:solr_delete_by_id).with(1)
|
75
|
-
@index.delete(1)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
describe "delete_by_query" do
|
80
|
-
it "should delete by query" do
|
81
|
-
@index.should_receive(:solr_delete_by_query).with("foo:bar")
|
82
|
-
@index.delete_by_query("foo:bar")
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe "flatten_and_expand" do
|
87
|
-
before(:each) do
|
88
|
-
@fields = Hash.new
|
89
|
-
end
|
90
|
-
|
91
|
-
it "should set a value for the parent as key, with the key as the value" do
|
92
|
-
@fields = @index.flatten_and_expand("omerta" => { "one" => "woot" })
|
93
|
-
@fields["omerta"].should == ["one"]
|
94
|
-
end
|
95
|
-
|
96
|
-
it "should call itself recursively for values that are hashes" do
|
97
|
-
@fields = @index.flatten_and_expand({ "one" => { "two" => "three", "four" => { "five" => "six" } }})
|
98
|
-
expected = {"one" => [ "two", "four" ],
|
99
|
-
"one_two" => ["three"],
|
100
|
-
"X_two" => ["three"],
|
101
|
-
"two" => ["three"],
|
102
|
-
"one_four" => ["five"],
|
103
|
-
"X_four" => ["five"],
|
104
|
-
"one_X" => [ "three", "five" ],
|
105
|
-
"one_four_five" => ["six"],
|
106
|
-
"X_four_five" => ["six"],
|
107
|
-
"one_X_five" => ["six"],
|
108
|
-
"one_four_X" => ["six"],
|
109
|
-
"five" => ["six"]}
|
110
|
-
expected.each do |k, v|
|
111
|
-
@fields[k].should == v
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
it "should call itself recursively for hashes nested in arrays" do
|
116
|
-
@fields = @index.flatten_and_expand({ :one => [ { :two => "three" }, { :four => { :five => "six" } } ] })
|
117
|
-
expected = {"one_X_five" => ["six"],
|
118
|
-
"one_four" => ["five"],
|
119
|
-
"one_X" => [ "three", "five" ],
|
120
|
-
"two" => ["three"],
|
121
|
-
"one_four_X" => ["six"],
|
122
|
-
"X_four" => ["five"],
|
123
|
-
"X_four_five" => ["six"],
|
124
|
-
"one" => [ "two", "four" ],
|
125
|
-
"one_four_five" => ["six"],
|
126
|
-
"five" => ["six"],
|
127
|
-
"X_two" => ["three"],
|
128
|
-
"one_two" => ["three"]}
|
129
|
-
|
130
|
-
expected.each do |key, expected_value|
|
131
|
-
@fields[key].should == expected_value
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
it "generates unlimited levels of expando fields when expanding" do
|
136
|
-
expected_keys = ["one",
|
137
|
-
"one_two",
|
138
|
-
"X_two",
|
139
|
-
"one_X",
|
140
|
-
"one_two_three",
|
141
|
-
"X_two_three",
|
142
|
-
"one_X_three",
|
143
|
-
"one_two_X",
|
144
|
-
"one_two_three_four",
|
145
|
-
"X_two_three_four",
|
146
|
-
"one_X_three_four",
|
147
|
-
"one_two_X_four",
|
148
|
-
"one_two_three_X",
|
149
|
-
"one_two_three_four_five",
|
150
|
-
"X_two_three_four_five",
|
151
|
-
"one_X_three_four_five",
|
152
|
-
"one_two_X_four_five",
|
153
|
-
"one_two_three_X_five",
|
154
|
-
"one_two_three_four_X",
|
155
|
-
"six",
|
156
|
-
"one_two_three_four_five_six",
|
157
|
-
"X_two_three_four_five_six",
|
158
|
-
"one_X_three_four_five_six",
|
159
|
-
"one_two_X_four_five_six",
|
160
|
-
"one_two_three_X_five_six",
|
161
|
-
"one_two_three_four_X_six",
|
162
|
-
"one_two_three_four_five_X"].sort
|
163
|
-
|
164
|
-
nested = {:one => {:two => {:three => {:four => {:five => {:six => :end}}}}}}
|
165
|
-
@fields = @index.flatten_and_expand(nested)
|
166
|
-
|
167
|
-
@fields.keys.sort.should include(*expected_keys)
|
168
|
-
end
|
169
|
-
|
170
|
-
end
|
171
|
-
|
172
|
-
describe "creating expando fields" do
|
173
|
-
def make_expando_fields(parts)
|
174
|
-
expando_fields = []
|
175
|
-
@index.each_expando_field(parts) { |ex| expando_fields << ex }
|
176
|
-
expando_fields
|
177
|
-
end
|
178
|
-
|
179
|
-
it "joins the fields with a big X" do
|
180
|
-
make_expando_fields(%w{foo bar baz qux}).should == ["X_bar_baz_qux", "foo_X_baz_qux", "foo_bar_X_qux", "foo_bar_baz_X"]
|
181
|
-
make_expando_fields(%w{foo bar baz}).should == ["X_bar_baz", "foo_X_baz", "foo_bar_X"]
|
182
|
-
make_expando_fields(%w{foo bar}).should == ["X_bar", "foo_X"]
|
183
|
-
make_expando_fields(%w{foo}).should == []
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join("#{File.dirname(__FILE__)}", '..', '..', 'spec_helper'))
|
2
|
-
|
3
|
-
describe Chef::Solr::Query do
|
4
|
-
before(:each) do
|
5
|
-
@query = Chef::Solr::Query.new
|
6
|
-
end
|
7
|
-
|
8
|
-
describe "initialize" do
|
9
|
-
it "should return a Chef::Solr::Query" do
|
10
|
-
@query.should be_a_kind_of(Chef::Solr::Query)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
data/spec/chef/solr_spec.rb
DELETED
@@ -1,301 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join("#{File.dirname(__FILE__)}", '..', 'spec_helper'))
|
2
|
-
require 'net/http'
|
3
|
-
|
4
|
-
describe Chef::Solr do
|
5
|
-
before(:each) do
|
6
|
-
@solr = Chef::Solr.new
|
7
|
-
end
|
8
|
-
|
9
|
-
describe "initialize" do
|
10
|
-
it "should create a new Chef::Solr object" do
|
11
|
-
@solr.should be_a_kind_of(Chef::Solr)
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should accept an alternate solr url" do
|
15
|
-
solr = Chef::Solr.new("http://example.com")
|
16
|
-
solr.solr_url.should eql("http://example.com")
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe "solr_select" do
|
21
|
-
before(:each) do
|
22
|
-
@http_response = mock(
|
23
|
-
"Net::HTTP::Response",
|
24
|
-
:kind_of? => Net::HTTPSuccess,
|
25
|
-
:body => "{ :some => :hash }"
|
26
|
-
)
|
27
|
-
@http = mock("Net::HTTP", :request => @http_response)
|
28
|
-
@solr.http = @http
|
29
|
-
end
|
30
|
-
|
31
|
-
describe "when the HTTP call is successful" do
|
32
|
-
it "should call get to /solr/select with the escaped query" do
|
33
|
-
Net::HTTP::Get.should_receive(:new).with(%r(q=hostname%3Alatte))
|
34
|
-
@solr.solr_select("chef_opscode", "node", :q => "hostname:latte")
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should call get to /solr/select with wt=ruby" do
|
38
|
-
Net::HTTP::Get.should_receive(:new).with(%r(wt=ruby))
|
39
|
-
@solr.solr_select("chef_opscode", "node", :q => "hostname:latte")
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should call get to /solr/select with indent=off" do
|
43
|
-
Net::HTTP::Get.should_receive(:new).with(%r(indent=off))
|
44
|
-
@solr.solr_select("chef_opscode", "node", :q => "hostname:latte")
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should call get to /solr/select with filter query" do
|
48
|
-
Net::HTTP::Get.should_receive(:new).with(/fq=%2BX_CHEF_database_CHEF_X%3Achef_opscode\+%2BX_CHEF_type_CHEF_X%3Anode/)
|
49
|
-
@solr.solr_select("chef_opscode", "node", :q => "hostname:latte")
|
50
|
-
end
|
51
|
-
|
52
|
-
it "should return the evaluated response body" do
|
53
|
-
res = @solr.solr_select("chef_opscode", "node", :q => "hostname:latte")
|
54
|
-
res.should == { :some => :hash }
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
describe "when the HTTP call is unsuccessful" do
|
59
|
-
[Timeout::Error, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EINVAL].each do |exception|
|
60
|
-
it "should rescue, log an error message, and raise a SolrConnectionError encountering exception #{exception}" do
|
61
|
-
lambda {
|
62
|
-
@http.should_receive(:request).with(instance_of(Net::HTTP::Get)).and_raise(exception)
|
63
|
-
Chef::Log.should_receive(:fatal).with(/Search Query to Solr '(.+?)' failed. Chef::Exceptions::SolrConnectionError exception: #{exception}:.+/)
|
64
|
-
@solr.solr_select("chef_opscode", "node", :q => "hostname:latte")
|
65
|
-
}.should raise_error(Chef::Exceptions::SolrConnectionError)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
it "should rescue, log an error message, and raise a SolrConnectionError when encountering exception NoMethodError and net/http closed? bug" do
|
70
|
-
lambda {
|
71
|
-
@no_method_error = NoMethodError.new("undefined method 'closed\?' for nil:NilClass")
|
72
|
-
@http.should_receive(:request).with(instance_of(Net::HTTP::Get)).and_raise(@no_method_error)
|
73
|
-
Chef::Log.should_receive(:fatal).with(/Search Query to Solr '(.+?)' failed. Chef::Exceptions::SolrConnectionError exception: Errno::ECONNREFUSED.+net\/http undefined method closed.+/)
|
74
|
-
@solr.solr_select("chef_opscode", "node", :q => "hostname:latte")
|
75
|
-
}.should raise_error(Chef::Exceptions::SolrConnectionError)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
describe "post_to_solr" do
|
81
|
-
before(:each) do
|
82
|
-
@http_response = mock(
|
83
|
-
"Net::HTTP::Response",
|
84
|
-
:kind_of? => Net::HTTPSuccess,
|
85
|
-
:body => "{ :some => :hash }"
|
86
|
-
)
|
87
|
-
@http_request = mock(
|
88
|
-
"Net::HTTP::Request",
|
89
|
-
:body= => true
|
90
|
-
)
|
91
|
-
@http = mock("Net::HTTP", :request => @http_response)
|
92
|
-
@solr.http = @http
|
93
|
-
Net::HTTP::Post.stub!(:new).and_return(@http_request)
|
94
|
-
@doc = { "foo" => "bar" }
|
95
|
-
end
|
96
|
-
|
97
|
-
describe 'when the HTTP call is successful' do
|
98
|
-
it "should post to /solr/update" do
|
99
|
-
Net::HTTP::Post.should_receive(:new).with("/solr/update", "Content-Type" => "text/xml").and_return(@http_request)
|
100
|
-
@solr.post_to_solr(@doc)
|
101
|
-
end
|
102
|
-
|
103
|
-
it "should set the body of the request to the stringified doc" do
|
104
|
-
@http_request.should_receive(:body=).with("foo")
|
105
|
-
@solr.post_to_solr(:foo)
|
106
|
-
end
|
107
|
-
|
108
|
-
it "should send the request to solr" do
|
109
|
-
@http.should_receive(:request).with(@http_request).and_return(@http_response)
|
110
|
-
@solr.post_to_solr(:foo).should
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
describe "when the HTTP call is unsuccessful due to an exception" do
|
115
|
-
it "should post to /solr/update" do
|
116
|
-
Net::HTTP::Post.should_receive(:new).with("/solr/update", "Content-Type" => "text/xml").and_return(@http_request)
|
117
|
-
@solr.post_to_solr(@doc)
|
118
|
-
end
|
119
|
-
|
120
|
-
it "should set the body of the request to the stringified doc" do
|
121
|
-
@http_request.should_receive(:body=).with("foo")
|
122
|
-
@solr.post_to_solr(:foo)
|
123
|
-
end
|
124
|
-
|
125
|
-
[Timeout::Error, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EINVAL].each do |exception|
|
126
|
-
it "should rescue and log an error message when encountering exception #{exception} and then re-raise it" do
|
127
|
-
lambda {
|
128
|
-
@http.should_receive(:request).with(@http_request).and_raise(exception)
|
129
|
-
Chef::Log.should_receive(:fatal).with(/POST to Solr '(.+?)' failed. Chef::Exceptions::SolrConnectionError exception: #{exception}:.+/)
|
130
|
-
@solr.post_to_solr(:foo)
|
131
|
-
}.should raise_error(Chef::Exceptions::SolrConnectionError)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
it "should rescue and log an error message when encountering exception NoMethodError and net/http closed? bug" do
|
136
|
-
lambda {
|
137
|
-
@no_method_error = NoMethodError.new("undefined method 'closed\?' for nil:NilClass")
|
138
|
-
@http.should_receive(:request).with(@http_request).and_raise(@no_method_error)
|
139
|
-
Chef::Log.should_receive(:fatal).with(/POST to Solr '(.+?)' failed. Chef::Exceptions::SolrConnectionError exception: Errno::ECONNREFUSED.+net\/http undefined method closed.+/)
|
140
|
-
@solr.post_to_solr(:foo)
|
141
|
-
}.should raise_error(Chef::Exceptions::SolrConnectionError)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
describe "solr_add" do
|
147
|
-
before(:each) do
|
148
|
-
@solr.stub!(:post_to_solr).and_return(true)
|
149
|
-
@data = { "foo" => ["bar"] }
|
150
|
-
end
|
151
|
-
|
152
|
-
it "should send valid XML to solr" do
|
153
|
-
@solr.should_receive(:post_to_solr).with("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<add><doc><field name=\"foo\">bar</field></doc></add>\n")
|
154
|
-
@solr.solr_add(@data)
|
155
|
-
end
|
156
|
-
|
157
|
-
it "XML escapes content before sending to SOLR" do
|
158
|
-
@data["foo"] = ["<&>"]
|
159
|
-
@solr.should_receive(:post_to_solr).with("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<add><doc><field name=\"foo\"><&></field></doc></add>\n")
|
160
|
-
|
161
|
-
@solr.solr_add(@data)
|
162
|
-
end
|
163
|
-
|
164
|
-
it "XML escapes keys before sending to SOLR" do
|
165
|
-
@data.delete("foo")
|
166
|
-
@data["foo&bar"] = ["baz"]
|
167
|
-
@solr.should_receive(:post_to_solr).with("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<add><doc><field name=\"foo&bar\">baz</field></doc></add>\n")
|
168
|
-
|
169
|
-
@solr.solr_add(@data)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
describe "solr_commit" do
|
174
|
-
before(:each) do
|
175
|
-
@solr.stub!(:post_to_solr).and_return(true)
|
176
|
-
end
|
177
|
-
|
178
|
-
it "should send valid commit xml to solr" do
|
179
|
-
@solr.should_receive(:post_to_solr).with("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<commit/>\n")
|
180
|
-
@solr.solr_commit
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
describe "solr_optimize" do
|
185
|
-
before(:each) do
|
186
|
-
@solr.stub!(:post_to_solr).and_return(true)
|
187
|
-
end
|
188
|
-
|
189
|
-
it "should send valid commit xml to solr" do
|
190
|
-
@solr.should_receive(:post_to_solr).with("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<optimize/>\n")
|
191
|
-
@solr.solr_optimize
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
describe "solr_rollback" do
|
196
|
-
before(:each) do
|
197
|
-
@solr.stub!(:post_to_solr).and_return(true)
|
198
|
-
end
|
199
|
-
|
200
|
-
it "should send valid commit xml to solr" do
|
201
|
-
@solr.should_receive(:post_to_solr).with("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<rollback/>\n")
|
202
|
-
@solr.solr_rollback
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
describe "solr_delete_by_id" do
|
207
|
-
before(:each) do
|
208
|
-
@solr.stub!(:post_to_solr).and_return(true)
|
209
|
-
end
|
210
|
-
|
211
|
-
it "should send valid delete id xml to solr" do
|
212
|
-
@solr.should_receive(:post_to_solr).with("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<delete><id>1</id></delete>\n")
|
213
|
-
@solr.solr_delete_by_id(1)
|
214
|
-
end
|
215
|
-
|
216
|
-
it "should accept multiple ids" do
|
217
|
-
@solr.should_receive(:post_to_solr).with("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<delete><id>1</id><id>2</id></delete>\n")
|
218
|
-
@solr.solr_delete_by_id([ 1, 2 ])
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
describe "solr_delete_by_query" do
|
223
|
-
before(:each) do
|
224
|
-
@solr.stub!(:post_to_solr).and_return(true)
|
225
|
-
end
|
226
|
-
|
227
|
-
it "should send valid delete id xml to solr" do
|
228
|
-
@solr.should_receive(:post_to_solr).with("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<delete><query>foo:bar</query></delete>\n")
|
229
|
-
@solr.solr_delete_by_query("foo:bar")
|
230
|
-
end
|
231
|
-
|
232
|
-
it "should accept multiple ids" do
|
233
|
-
@solr.should_receive(:post_to_solr).with("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<delete><query>foo:bar</query><query>baz:bum</query></delete>\n")
|
234
|
-
@solr.solr_delete_by_query([ "foo:bar", "baz:bum" ])
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
describe "rebuilding the index" do
|
239
|
-
before do
|
240
|
-
Chef::Config[:couchdb_database] = "chunky_bacon"
|
241
|
-
end
|
242
|
-
|
243
|
-
it "deletes the index and commits" do
|
244
|
-
@solr.should_receive(:solr_delete_by_query).with("X_CHEF_database_CHEF_X:chunky_bacon")
|
245
|
-
@solr.should_receive(:solr_commit)
|
246
|
-
@solr.stub!(:reindex_all)
|
247
|
-
Chef::DataBag.stub!(:cdb_list).and_return([])
|
248
|
-
@solr.rebuild_index
|
249
|
-
end
|
250
|
-
|
251
|
-
it "reindexes Chef::ApiClient, Chef::Node, and Chef::Role objects, reporting the results as a hash" do
|
252
|
-
@solr.stub!(:solr_delete_by_query).with("X_CHEF_database_CHEF_X:chunky_bacon")
|
253
|
-
@solr.stub!(:solr_commit)
|
254
|
-
@solr.should_receive(:reindex_all).with(Chef::ApiClient).and_return(true)
|
255
|
-
@solr.should_receive(:reindex_all).with(Chef::Node).and_return(true)
|
256
|
-
@solr.should_receive(:reindex_all).with(Chef::Role).and_return(true)
|
257
|
-
Chef::DataBag.stub!(:cdb_list).and_return([])
|
258
|
-
|
259
|
-
result = @solr.rebuild_index
|
260
|
-
result["Chef::ApiClient"].should == "success"
|
261
|
-
result["Chef::Node"].should == "success"
|
262
|
-
result["Chef::Role"].should == "success"
|
263
|
-
end
|
264
|
-
|
265
|
-
it "does not reindex Chef::OpenIDRegistration or Chef::WebUIUser objects" do
|
266
|
-
# hi there. the reason we're specifying this behavior is because these objects
|
267
|
-
# are not properly indexed in the first place and trying to reindex them
|
268
|
-
# tickles a bug in our CamelCase to snake_case code. See CHEF-1009.
|
269
|
-
@solr.stub!(:solr_delete_by_query).with("X_CHEF_database_CHEF_X:chunky_bacon")
|
270
|
-
@solr.stub!(:solr_commit)
|
271
|
-
@solr.stub!(:reindex_all).with(Chef::ApiClient)
|
272
|
-
@solr.stub!(:reindex_all).with(Chef::Node)
|
273
|
-
@solr.stub!(:reindex_all).with(Chef::Role)
|
274
|
-
@solr.should_not_receive(:reindex_all).with(Chef::OpenIDRegistration)
|
275
|
-
@solr.should_not_receive(:reindex_all).with(Chef::WebUIUser)
|
276
|
-
Chef::DataBag.stub!(:cdb_list).and_return([])
|
277
|
-
|
278
|
-
@solr.rebuild_index
|
279
|
-
end
|
280
|
-
|
281
|
-
it "reindexes databags" do
|
282
|
-
one_data_item = Chef::DataBagItem.new
|
283
|
-
one_data_item.raw_data = {"maybe"=>"snakes actually are evil", "id" => "just_sayin"}
|
284
|
-
two_data_item = Chef::DataBagItem.new
|
285
|
-
two_data_item.raw_data = {"tone_depth"=>"rumble_fish", "id" => "eff_yes"}
|
286
|
-
data_bag = Chef::DataBag.new
|
287
|
-
data_bag.stub!(:list).and_return([one_data_item, two_data_item])
|
288
|
-
|
289
|
-
@solr.stub!(:solr_delete_by_query).with("X_CHEF_database_CHEF_X:chunky_bacon")
|
290
|
-
@solr.stub!(:solr_commit)
|
291
|
-
@solr.stub!(:reindex_all)
|
292
|
-
Chef::DataBag.stub!(:cdb_list).and_return([data_bag])
|
293
|
-
|
294
|
-
data_bag.should_receive(:add_to_index)
|
295
|
-
one_data_item.should_receive(:add_to_index)
|
296
|
-
two_data_item.should_receive(:add_to_index)
|
297
|
-
|
298
|
-
@solr.rebuild_index["Chef::DataBag"].should == "success"
|
299
|
-
end
|
300
|
-
end
|
301
|
-
end
|