solr_wrapper 0.0.7 → 1.0.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.
- checksums.yaml +4 -4
- data/.hound.yml +2 -0
- data/.rspec +2 -0
- data/.rubocop.yml +16 -0
- data/.rubocop_todo.yml +0 -0
- data/.travis.yml +10 -5
- data/Gemfile +1 -1
- data/README.md +81 -6
- data/Rakefile +1 -2
- data/exe/solr_wrapper +125 -0
- data/lib/solr_wrapper/client.rb +36 -0
- data/lib/solr_wrapper/configuration.rb +163 -0
- data/lib/solr_wrapper/downloader.rb +25 -0
- data/lib/solr_wrapper/instance.rb +238 -175
- data/lib/solr_wrapper/md5.rb +43 -0
- data/lib/solr_wrapper/rake_task.rb +5 -0
- data/lib/solr_wrapper/settings.rb +148 -0
- data/lib/solr_wrapper/tasks/solr_wrapper.rake +45 -0
- data/lib/solr_wrapper/version.rb +2 -2
- data/lib/solr_wrapper.rb +32 -6
- data/solr_wrapper.gemspec +4 -1
- data/spec/fixtures/another_sample_config.yml +2 -0
- data/spec/fixtures/sample_config.yml +8 -0
- data/spec/lib/solr_wrapper/client_spec.rb +25 -0
- data/spec/lib/solr_wrapper/configuration_spec.rb +86 -0
- data/spec/lib/solr_wrapper/instance_spec.rb +154 -7
- data/spec/lib/solr_wrapper_spec.rb +18 -3
- data/spec/spec_helper.rb +5 -3
- metadata +54 -5
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
require 'delegate'
|
|
2
|
+
require 'faraday'
|
|
3
|
+
|
|
4
|
+
module SolrWrapper
|
|
5
|
+
# Configuraton that comes from static and dynamic sources.
|
|
6
|
+
class Settings < Delegator
|
|
7
|
+
|
|
8
|
+
def __getobj__
|
|
9
|
+
@static_config # return object we are delegating to, required
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
alias static_config __getobj__
|
|
13
|
+
|
|
14
|
+
def __setobj__(obj)
|
|
15
|
+
@static_config = obj
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def initialize(static_config)
|
|
19
|
+
super
|
|
20
|
+
@static_config = static_config
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# Get the host this Solr instance is bound to
|
|
25
|
+
def host
|
|
26
|
+
'127.0.0.1'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def zookeeper_host
|
|
30
|
+
@zookeeper_host ||= static_config.zookeeper_port
|
|
31
|
+
@zookeeper_host ||= host
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
# Get the port this Solr instance is running at
|
|
36
|
+
def port
|
|
37
|
+
@port ||= static_config.port
|
|
38
|
+
@port ||= random_open_port.to_s
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def zookeeper_port
|
|
42
|
+
@zookeeper_port ||= static_config.zookeeper_port
|
|
43
|
+
@zookeeper_port ||= "#{port.to_i + 1000}"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
##
|
|
48
|
+
# Get a (likely) URL to the solr instance
|
|
49
|
+
def url
|
|
50
|
+
"http://#{host}:#{port}/solr/"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def instance_dir
|
|
54
|
+
@instance_dir ||= static_config.instance_dir
|
|
55
|
+
@instance_dir ||= File.join(tmpdir, File.basename(download_url, ".zip"))
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def managed?
|
|
59
|
+
File.exist?(instance_dir)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def download_url
|
|
63
|
+
@download_url ||= static_config.url
|
|
64
|
+
@download_url ||= default_download_url
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def solr_zip_path
|
|
68
|
+
@solr_zip_path ||= static_config.solr_zip_path
|
|
69
|
+
@solr_zip_path ||= default_solr_zip_path
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def version_file
|
|
73
|
+
static_config.version_file || File.join(instance_dir, "VERSION")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def md5url
|
|
77
|
+
if default_download_url == archive_download_url
|
|
78
|
+
"#{archive_download_url}.md5"
|
|
79
|
+
else
|
|
80
|
+
"http://www.us.apache.org/dist/lucene/solr/#{static_config.version}/solr-#{static_config.version}.zip.md5"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def md5sum_path
|
|
85
|
+
File.join(download_dir, File.basename(md5url))
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def solr_binary
|
|
89
|
+
File.join(instance_dir, "bin", "solr")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def tmp_save_dir
|
|
93
|
+
@tmp_save_dir ||= Dir.mktmpdir
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
|
|
98
|
+
def tmpdir
|
|
99
|
+
if defined?(Rails) && Rails.root
|
|
100
|
+
File.join(Rails.root, 'tmp')
|
|
101
|
+
else
|
|
102
|
+
Dir.tmpdir
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def default_solr_zip_path
|
|
107
|
+
File.join(download_dir, File.basename(download_url))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def download_dir
|
|
111
|
+
@download_dir ||= static_config.download_dir
|
|
112
|
+
FileUtils.mkdir_p @download_dir
|
|
113
|
+
@download_dir
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def default_download_url
|
|
117
|
+
@default_url ||= begin
|
|
118
|
+
json = open(static_config.mirror_url).read
|
|
119
|
+
doc = JSON.parse(json)
|
|
120
|
+
url = doc['preferred'] + doc['path_info']
|
|
121
|
+
|
|
122
|
+
response = Faraday.head(url)
|
|
123
|
+
|
|
124
|
+
if response.success?
|
|
125
|
+
url
|
|
126
|
+
else
|
|
127
|
+
archive_download_url
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
rescue Errno::ECONNRESET, SocketError, Faraday::Error
|
|
131
|
+
archive_download_url
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def archive_download_url
|
|
135
|
+
"https://archive.apache.org/dist/lucene/solr/#{static_config.version}/solr-#{static_config.version}.zip"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def random_open_port
|
|
139
|
+
socket = Socket.new(:INET, :STREAM, 0)
|
|
140
|
+
begin
|
|
141
|
+
socket.bind(Addrinfo.tcp('127.0.0.1', 0))
|
|
142
|
+
socket.local_address.ip_port
|
|
143
|
+
ensure
|
|
144
|
+
socket.close
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'solr_wrapper'
|
|
2
|
+
|
|
3
|
+
## These tasks get loaded into the host context when solr_wrapper is required
|
|
4
|
+
namespace :solr do
|
|
5
|
+
desc "Load the solr options and solr instance"
|
|
6
|
+
task :environment do
|
|
7
|
+
@solr_instance = SolrWrapper.default_instance
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
desc 'Install a clean version of solr. Replaces the existing copy if there is one.'
|
|
11
|
+
task clean: :environment do
|
|
12
|
+
puts "Installing clean version of solr at #{File.expand_path(@solr_instance.instance_dir)}"
|
|
13
|
+
@solr_instance.remove_instance_dir!
|
|
14
|
+
@solr_instance.extract_and_configure
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
desc 'start solr'
|
|
18
|
+
task start: :environment do
|
|
19
|
+
begin
|
|
20
|
+
puts "Starting solr at #{@solr_instance.config.url}"
|
|
21
|
+
@solr_instance.start
|
|
22
|
+
rescue => e
|
|
23
|
+
if e.message.include?("Port #{@solr_instance.port} is already being used by another process")
|
|
24
|
+
puts "FAILED. Port #{@solr_instance.port} is already being used."
|
|
25
|
+
puts " Did you already have solr running?"
|
|
26
|
+
puts " a) YES: Continue as you were. Solr is running."
|
|
27
|
+
puts " b) NO: Either set SOLR_OPTIONS[:port] to a different value or stop the process that's using port #{@solr_instance.port}."
|
|
28
|
+
else
|
|
29
|
+
raise "Failed to start solr. #{e.class}: #{e.message}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
desc 'restart solr'
|
|
35
|
+
task restart: :environment do
|
|
36
|
+
puts "Restarting solr"
|
|
37
|
+
@solr_instance.restart
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
desc 'stop solr'
|
|
41
|
+
task stop: :environment do
|
|
42
|
+
@solr_instance.stop
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
data/lib/solr_wrapper/version.rb
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
module SolrWrapper
|
|
2
|
-
VERSION =
|
|
3
|
-
end
|
|
2
|
+
VERSION = '1.0.0'
|
|
3
|
+
end
|
data/lib/solr_wrapper.rb
CHANGED
|
@@ -1,18 +1,44 @@
|
|
|
1
1
|
require 'solr_wrapper/version'
|
|
2
|
+
require 'solr_wrapper/configuration'
|
|
3
|
+
require 'solr_wrapper/settings'
|
|
4
|
+
require 'solr_wrapper/md5'
|
|
5
|
+
require 'solr_wrapper/downloader'
|
|
2
6
|
require 'solr_wrapper/instance'
|
|
7
|
+
require 'solr_wrapper/client'
|
|
3
8
|
|
|
4
9
|
module SolrWrapper
|
|
5
10
|
def self.default_solr_version
|
|
6
|
-
|
|
11
|
+
'latest'
|
|
7
12
|
end
|
|
8
13
|
|
|
9
|
-
def self.
|
|
10
|
-
|
|
14
|
+
def self.default_solr_port
|
|
15
|
+
'8983'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.default_instance_options
|
|
19
|
+
@default_instance_options ||= {
|
|
20
|
+
port: SolrWrapper.default_solr_port,
|
|
21
|
+
version: SolrWrapper.default_solr_version
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.default_instance_options=(options)
|
|
26
|
+
@default_instance_options = options
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.default_instance(options = {})
|
|
30
|
+
@default_instance ||= instance(default_instance_options)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.instance(options = {})
|
|
34
|
+
SolrWrapper::Instance.new(options)
|
|
11
35
|
end
|
|
12
36
|
|
|
13
37
|
##
|
|
14
38
|
# Ensures a Solr service is running before executing the block
|
|
15
|
-
def self.wrap
|
|
16
|
-
|
|
39
|
+
def self.wrap(options = {}, &block)
|
|
40
|
+
instance(options).wrap &block
|
|
17
41
|
end
|
|
18
|
-
|
|
42
|
+
|
|
43
|
+
class SolrWrapperError < StandardError; end
|
|
44
|
+
end
|
data/solr_wrapper.gemspec
CHANGED
|
@@ -13,10 +13,12 @@ Gem::Specification.new do |spec|
|
|
|
13
13
|
spec.license = "MIT"
|
|
14
14
|
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0")
|
|
16
|
-
spec.
|
|
16
|
+
spec.bindir = 'exe'
|
|
17
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
17
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
18
19
|
spec.require_paths = ["lib"]
|
|
19
20
|
|
|
21
|
+
spec.add_dependency "faraday"
|
|
20
22
|
spec.add_dependency "rubyzip"
|
|
21
23
|
spec.add_dependency "ruby-progressbar"
|
|
22
24
|
|
|
@@ -26,4 +28,5 @@ Gem::Specification.new do |spec|
|
|
|
26
28
|
spec.add_development_dependency "rspec"
|
|
27
29
|
spec.add_development_dependency "simple_solr_client"
|
|
28
30
|
spec.add_development_dependency "coveralls"
|
|
31
|
+
spec.add_development_dependency "webmock"
|
|
29
32
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe SolrWrapper::Client do
|
|
4
|
+
subject { described_class.new('http://localhost:8983/solr/') }
|
|
5
|
+
|
|
6
|
+
describe '#exists?' do
|
|
7
|
+
it 'checks if a solrcloud collection exists' do
|
|
8
|
+
stub_request(:get, 'http://localhost:8983/solr/admin/collections?action=LIST&wt=json').to_return(body: '{ "collections": ["x", "y", "z"]}')
|
|
9
|
+
stub_request(:get, 'http://localhost:8983/solr/admin/cores?action=STATUS&wt=json&core=a').to_return(body: '{ "status": { "a": {} } }')
|
|
10
|
+
|
|
11
|
+
expect(subject.exists?('x')).to eq true
|
|
12
|
+
expect(subject.exists?('a')).to eq false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'checks if a solr core exists' do
|
|
16
|
+
stub_request(:get, 'http://localhost:8983/solr/admin/collections?action=LIST&wt=json').to_return(body: '{ "error": { "msg": "Solr instance is not running in SolrCloud mode."} }')
|
|
17
|
+
|
|
18
|
+
stub_request(:get, 'http://localhost:8983/solr/admin/cores?action=STATUS&wt=json&core=x').to_return(body: '{ "status": { "x": { "name": "x" } } }')
|
|
19
|
+
stub_request(:get, 'http://localhost:8983/solr/admin/cores?action=STATUS&wt=json&core=a').to_return(body: '{ "status": { "a": {} } }')
|
|
20
|
+
|
|
21
|
+
expect(subject.exists?('x')).to eq true
|
|
22
|
+
expect(subject.exists?('a')).to eq false
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe SolrWrapper::Configuration do
|
|
4
|
+
let(:config) { described_class.new options }
|
|
5
|
+
|
|
6
|
+
describe "#port" do
|
|
7
|
+
subject { config.port }
|
|
8
|
+
|
|
9
|
+
context "when port is set to nil" do
|
|
10
|
+
let(:options) { { port: nil } }
|
|
11
|
+
it { is_expected.to eq nil }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context "when port is not set" do
|
|
15
|
+
let(:options) { {} }
|
|
16
|
+
it { is_expected.to eq '8983' }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context "when a port is provided" do
|
|
20
|
+
let(:options) { { port: '8888' } }
|
|
21
|
+
it { is_expected.to eq '8888' }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe "#load_configs" do
|
|
26
|
+
before do
|
|
27
|
+
allow(config).to receive(:default_configuration_paths).and_return([])
|
|
28
|
+
end
|
|
29
|
+
context 'with a single config file' do
|
|
30
|
+
let(:options) { { config: 'spec/fixtures/sample_config.yml' } }
|
|
31
|
+
it "uses values from the config file" do
|
|
32
|
+
expect(config.port).to eq '9999'
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
context 'with multiple config files' do
|
|
36
|
+
let(:options) { { config: ['spec/fixtures/sample_config.yml', 'spec/fixtures/another_sample_config.yml'] } }
|
|
37
|
+
it "uses values from the config file" do
|
|
38
|
+
expect(config.port).to eq '9998'
|
|
39
|
+
expect(config.verbose?).to eq true
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe "#collection_options" do
|
|
45
|
+
before do
|
|
46
|
+
allow(config).to receive(:default_configuration_paths).and_return([])
|
|
47
|
+
end
|
|
48
|
+
let(:options) { { config: 'spec/fixtures/sample_config.yml' } }
|
|
49
|
+
it "uses values from the config file" do
|
|
50
|
+
expect(config.collection_options).to eq(name: 'project-development', dir: 'solr/config/', persist: false)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe '#configsets' do
|
|
55
|
+
before do
|
|
56
|
+
allow(config).to receive(:default_configuration_paths).and_return([])
|
|
57
|
+
end
|
|
58
|
+
let(:options) { { config: 'spec/fixtures/sample_config.yml' } }
|
|
59
|
+
|
|
60
|
+
it 'uses values from the config file' do
|
|
61
|
+
expect(config.configsets).to include(name: 'project-development-configset', dir: 'solr/config/')
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe '#version' do
|
|
66
|
+
context 'when it is a version number' do
|
|
67
|
+
let(:options) { { version: 'x.y.z' } }
|
|
68
|
+
|
|
69
|
+
it 'uses that version' do
|
|
70
|
+
expect(config.version).to eq 'x.y.z'
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context 'when it is "latest"' do
|
|
75
|
+
let(:options) { { version: 'latest'} }
|
|
76
|
+
|
|
77
|
+
before do
|
|
78
|
+
stub_request(:get, 'https://svn.apache.org/repos/asf/lucene/cms/trunk/content/latestversion.mdtext').to_return(body: 'z.y.x')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'fetches the latest version number from apache' do
|
|
82
|
+
expect(config.version).to eq 'z.y.x'
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -1,19 +1,166 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe SolrWrapper::Instance do
|
|
4
|
-
|
|
5
|
-
let(:
|
|
4
|
+
let(:options) { {} }
|
|
5
|
+
let(:solr_instance) { SolrWrapper::Instance.new(options) }
|
|
6
|
+
subject { solr_instance }
|
|
7
|
+
let(:client) { SimpleSolrClient::Client.new(subject.url) }
|
|
8
|
+
|
|
6
9
|
describe "#with_collection" do
|
|
7
|
-
|
|
10
|
+
let(:options) { { cloud: false } }
|
|
11
|
+
context "without a name" do
|
|
12
|
+
it "creates a new anonymous collection" do
|
|
13
|
+
subject.wrap do |solr|
|
|
14
|
+
solr.with_collection(dir: File.join(FIXTURES_DIR, "basic_configs")) do |collection_name|
|
|
15
|
+
core = client.core(collection_name)
|
|
16
|
+
unless defined? JRUBY_VERSION
|
|
17
|
+
expect(core.schema.field('id').name).to eq 'id'
|
|
18
|
+
expect(core.schema.field('id').stored).to eq true
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
context "with a config file" do
|
|
25
|
+
before do
|
|
26
|
+
allow(solr_instance.config).to receive(:collection_options)
|
|
27
|
+
.and_return(name: 'project-development', dir: 'solr/config/')
|
|
28
|
+
allow(solr_instance).to receive(:delete)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "creates a new collection with options from the config" do
|
|
32
|
+
expect(solr_instance).to receive(:create).with(
|
|
33
|
+
hash_including(name: "project-development", dir: anything))
|
|
34
|
+
solr_instance.with_collection(dir: File.join(FIXTURES_DIR, "basic_configs")) {}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context 'persistent collections' do
|
|
39
|
+
it "creates a new collection with options from the config" do
|
|
40
|
+
expect(solr_instance).to receive(:create).with(
|
|
41
|
+
hash_including(name: 'project-development'))
|
|
42
|
+
expect(solr_instance).not_to receive(:delete)
|
|
43
|
+
solr_instance.with_collection(name: 'project-development', dir: 'solr/config/', persist: true) {}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe 'single solr node' do
|
|
47
|
+
it 'allows persistent collection on restart' do
|
|
48
|
+
subject.wrap do |solr|
|
|
49
|
+
solr.with_collection(name: 'solr-node-persistent-core', dir: File.join(FIXTURES_DIR, 'basic_configs'), persist: true) {}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
subject.wrap do |solr|
|
|
53
|
+
solr.with_collection(name: 'solr-node-persistent-core', dir: File.join(FIXTURES_DIR, 'basic_configs'), persist: true) {}
|
|
54
|
+
solr.delete 'solr-node-persistent-core'
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe 'solr cloud' do
|
|
60
|
+
let(:options) { { cloud: true } }
|
|
61
|
+
|
|
62
|
+
it 'allows persistent collection on restart' do
|
|
63
|
+
subject.wrap do |solr|
|
|
64
|
+
config_name = solr.upconfig dir: File.join(FIXTURES_DIR, 'basic_configs')
|
|
65
|
+
solr.with_collection(name: 'solr-cloud-persistent-collection', config_name: config_name, persist: true) {}
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
subject.wrap do |solr|
|
|
69
|
+
solr.with_collection(name: 'solr-cloud-persistent-collection', persist: true) {}
|
|
70
|
+
solr.delete 'solr-cloud-persistent-collection'
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context 'with a SolrCloud instance' do
|
|
78
|
+
let(:options) { { cloud: true } }
|
|
79
|
+
it 'can upload configurations' do
|
|
8
80
|
subject.wrap do |solr|
|
|
9
|
-
solr.
|
|
81
|
+
config_name = solr.upconfig dir: File.join(FIXTURES_DIR, 'basic_configs')
|
|
82
|
+
Dir.mktmpdir do |dir|
|
|
83
|
+
solr.downconfig name: config_name, dir: dir
|
|
84
|
+
end
|
|
85
|
+
solr.with_collection(config_name: config_name) do |collection_name|
|
|
10
86
|
core = client.core(collection_name)
|
|
11
87
|
unless defined? JRUBY_VERSION
|
|
12
|
-
expect(core.
|
|
13
|
-
expect(core.schema.field('id').stored).to eq true
|
|
88
|
+
expect(core.all.size).to eq 0
|
|
14
89
|
end
|
|
15
90
|
end
|
|
16
91
|
end
|
|
17
92
|
end
|
|
93
|
+
|
|
94
|
+
context 'with a config file' do
|
|
95
|
+
before do
|
|
96
|
+
allow(solr_instance.config).to receive(:configsets)
|
|
97
|
+
.and_return([name: 'project-development', dir: 'solr/config/'])
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'creates a new configsets with options from the config' do
|
|
101
|
+
expect(subject).to receive(:upconfig).with(
|
|
102
|
+
hash_including(name: 'project-development', dir: anything))
|
|
103
|
+
|
|
104
|
+
subject.wrap do
|
|
105
|
+
# no-op
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
describe 'exec' do
|
|
112
|
+
let(:cmd) { 'start' }
|
|
113
|
+
let(:options) { { p: '4098', help: true } }
|
|
114
|
+
subject { solr_instance.send(:exec, cmd, options) }
|
|
115
|
+
it 'runs the command' do
|
|
116
|
+
result_io = subject
|
|
117
|
+
expect(result_io.read).to include('Usage: solr start')
|
|
118
|
+
end
|
|
119
|
+
it 'accepts boolean flags' do
|
|
120
|
+
result_io = solr_instance.send(:exec, 'start', p: '4098', help: true)
|
|
121
|
+
expect(result_io.read).to include('Usage: solr start')
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
describe 'when something goes wrong' do
|
|
125
|
+
let(:cmd) { 'healthcheck' }
|
|
126
|
+
let(:options) { { z: 'localhost:5098' } }
|
|
127
|
+
it 'raises an error with the output from the shell command' do
|
|
128
|
+
expect { subject }.to raise_error(RuntimeError, /Failed to execute solr healthcheck: collection parameter is required!/)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
describe "#host" do
|
|
134
|
+
subject { solr_instance.host }
|
|
135
|
+
it { is_expected.to eq '127.0.0.1' }
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
describe "#port" do
|
|
139
|
+
subject { solr_instance.port }
|
|
140
|
+
it { is_expected.to eq '8983' }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
describe "#url" do
|
|
144
|
+
subject { solr_instance.url }
|
|
145
|
+
it { is_expected.to eq 'http://127.0.0.1:8983/solr/' }
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
describe "#instance_dir" do
|
|
149
|
+
subject { solr_instance.instance_dir }
|
|
150
|
+
it { is_expected.to start_with Dir.tmpdir }
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
describe "#version" do
|
|
154
|
+
before do
|
|
155
|
+
allow(solr_instance.config).to receive(:version).and_return('solr-version-number')
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
subject { solr_instance.version }
|
|
159
|
+
it { is_expected.to eq 'solr-version-number' }
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
describe "#md5" do
|
|
163
|
+
subject { solr_instance.md5 }
|
|
164
|
+
it { is_expected.to be_instance_of SolrWrapper::MD5 }
|
|
18
165
|
end
|
|
19
|
-
end
|
|
166
|
+
end
|
|
@@ -4,12 +4,27 @@ describe SolrWrapper do
|
|
|
4
4
|
describe ".wrap" do
|
|
5
5
|
it "should launch solr" do
|
|
6
6
|
SolrWrapper.wrap do |solr|
|
|
7
|
-
expect
|
|
7
|
+
expect do
|
|
8
8
|
Timeout::timeout(15) do
|
|
9
9
|
TCPSocket.new('127.0.0.1', solr.port).close
|
|
10
10
|
end
|
|
11
|
-
|
|
11
|
+
end.not_to raise_exception
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
|
-
|
|
15
|
+
|
|
16
|
+
describe '.instance' do
|
|
17
|
+
context 'without arguments' do
|
|
18
|
+
it 'inherits the defaults' do
|
|
19
|
+
expect(SolrWrapper.instance.port).to eq '8983'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe ".default_instance_options=" do
|
|
25
|
+
it "sets default options" do
|
|
26
|
+
SolrWrapper.default_instance_options = { port: '1234' }
|
|
27
|
+
expect(SolrWrapper.default_instance_options[:port]). to eq '1234'
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -5,9 +5,11 @@ require 'solr_wrapper'
|
|
|
5
5
|
require 'simple_solr_client'
|
|
6
6
|
|
|
7
7
|
require 'rspec'
|
|
8
|
+
require 'webmock/rspec'
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
WebMock.allow_net_connect!
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
FIXTURES_DIR = File.expand_path("fixtures", File.dirname(__FILE__))
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
RSpec.configure do |_config|
|
|
15
|
+
end
|