elasticsearch-extensions 0.0.21 → 0.0.22

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9d1007e770ea632d144aed7e8d7d74f8eb4e9527
4
- data.tar.gz: 1a98abf5d303f796b5b96c40bd306085d4cde8e2
3
+ metadata.gz: 33490d5d862da6d64e26435f1a77291e2a0a82d5
4
+ data.tar.gz: 7b57c8185dde5a4278c142c1de61605e3107ff39
5
5
  SHA512:
6
- metadata.gz: cbbf6b9033cee7d278c8ef22df5996b6503e485c6fd493620967c0a8c4b2d1fc8acca3b54331f165167435716e4f445c51ea435e4cd7e51370dbc990f4c86fcd
7
- data.tar.gz: aa3855bede2446ac3784afa8d9080beb19370cdba44e22899ecd439e83ac022ad2fc8de0bbdc0a2e0db907495ae8f9bc813f0c815617e62ab6c45cdfead731a3
6
+ metadata.gz: 36cee1857c1fbea9d28821cb54d425df5a38f28c9d23a2a3ebd827ad29cb9f7ec004405e8b0e85176a199355ddb0ae9650980988b036f209581197f9af71d58a
7
+ data.tar.gz: 4a8a001059bd6982c26a21663fceb8298711cc0b73ddefd17e7be26aa97cf0e540ca7f2a5327a274f1d3c700662ecd89c58eaa8ed954eda62975ec6f97b0771c
data/Rakefile CHANGED
@@ -36,7 +36,7 @@ namespace :test do
36
36
  Rake::TestTask.new(:all) do |test|
37
37
  Rake::Task['test:ci_reporter'].invoke if ENV['CI']
38
38
  test.libs << 'lib' << 'test'
39
- test.test_files = FileList["test/**/unit/**/*_test.rb", "test/**/unit/**/*_test.rb"]
39
+ test.test_files = FileList["test/**/unit/**/*_test.rb", "test/**/integration/**/*_test.rb"]
40
40
  end
41
41
 
42
42
  Rake::TestTask.new(:profile) do |test|
@@ -21,110 +21,93 @@ module Elasticsearch
21
21
  module Extensions
22
22
  module Test
23
23
 
24
- # A convenience Ruby class for starting and stopping a separate testing in-memory cluster,
25
- # to not depend on -- and not mess up -- <localhost:9200>.
24
+ # A convenience Ruby class for starting and stopping an Elasticsearch cluster,
25
+ # eg. for integration tests
26
26
  #
27
27
  # @example Start a cluster with default configuration
28
28
  # require 'elasticsearch/extensions/test/cluster'
29
- # Elasticsearch::Extensions::Test::Cluster.start
29
+ # Elasticsearch::Extensions::Test::Cluster::Cluster.new.start
30
30
  #
31
- # @see Cluster#start Cluster.start
32
- # @see Cluster#stop Cluster.stop
31
+ # @see Cluster#initialize
33
32
  #
34
33
  module Cluster
35
- @@network_host = ENV.fetch('TEST_CLUSTER_NETWORK_HOST', 'localhost')
36
- @@number_of_nodes = (ENV['TEST_CLUSTER_NODES'] || 2).to_i
37
- @@default_cluster_name = "elasticsearch-test-#{Socket.gethostname.downcase}"
38
34
 
39
35
  # Starts a cluster
40
36
  #
41
- # Launches the specified number of nodes in test-suitable configuration by default
42
- # and prints information about the cluster -- unless this specific cluster is running already.
37
+ # @see Cluster#start
43
38
  #
44
- # Use the {Cluster#stop Cluster.stop} command with the same arguments to stop this cluster.
45
- #
46
- # @option arguments [String] :cluster_name Cluster name (default: `elasticsearch_test`)
47
- # @option arguments [Integer] :nodes Number of desired nodes (default: 2)
48
- # @option arguments [String] :command Elasticsearch command (default: `elasticsearch`)
49
- # @option arguments [String] :port Starting port number; will be auto-incremented (default: 9250)
50
- # @option arguments [String] :node_name The node name (will be appended with a number)
51
- # @option arguments [String] :path_data Path to the directory to store data in
52
- # @option arguments [String] :path_work Path to the directory with auxiliary files
53
- # @option arguments [String] :path_logs Path to the directory with log files
54
- # @option arguments [Boolean] :multicast_enabled Whether multicast is enabled (default: true)
55
- # @option arguments [Integer] :timeout Timeout when starting the cluster (default: 30)
56
- # @option arguments [String] :network_host The host that nodes will bind on and publish to
57
- # @option arguments [Boolean] :clear_cluster Wipe out cluster content on startup (default: true)
39
+ def start(arguments={})
40
+ Cluster.new(arguments).start
41
+ end
42
+
43
+ # Stops a cluster
58
44
  #
59
- # You can also use environment variables to set these options.
45
+ # @see Cluster#stop
60
46
  #
61
- # @example Start a cluster with default configuration (2 nodes, in-memory, etc)
62
- # Elasticsearch::Extensions::Test::Cluster.start
47
+ def stop(arguments={})
48
+ Cluster.new(arguments).stop
49
+ end
50
+
51
+ # Returns true when a specific test node is running within the cluster
63
52
  #
64
- # @example Start a cluster with a custom configuration
65
- # Elasticsearch::Extensions::Test::Cluster.start \
66
- # cluster_name: 'my-cluster',
67
- # nodes: 3,
68
- # node_name: 'my-node',
69
- # port: 9350
53
+ # @see Cluster#running?
70
54
  #
71
- # @example Start a cluster with a different Elasticsearch version
72
- # Elasticsearch::Extensions::Test::Cluster.start \
73
- # command: "/usr/local/Cellar/elasticsearch/1.0.0.Beta2/bin/elasticsearch"
55
+ def running?(arguments={})
56
+ Cluster.new(arguments).running?
57
+ end
58
+
59
+ # Waits until the cluster is green and prints information
74
60
  #
75
- # @return Boolean
76
- # @see Cluster#stop Cluster.stop
61
+ # @see Cluster#wait_for_green
77
62
  #
78
- def start(arguments={})
79
- @@number_of_nodes = ( ENV.fetch('TEST_CLUSTER_NODES', arguments[:nodes] || 2) ).to_i
80
-
81
- arguments[:command] ||= ENV.fetch('TEST_CLUSTER_COMMAND', 'elasticsearch')
82
- arguments[:port] ||= (ENV.fetch('TEST_CLUSTER_PORT', 9250).to_i)
83
- arguments[:cluster_name] ||= (ENV.fetch('TEST_CLUSTER_NAME', @@default_cluster_name).chomp)
84
- arguments[:node_name] ||= ENV.fetch('TEST_CLUSTER_NODE_NAME', 'node')
85
- arguments[:path_data] ||= ENV.fetch('TEST_CLUSTER_DATA', '/tmp/elasticsearch_test')
86
- arguments[:path_work] ||= ENV.fetch('TEST_CLUSTER_TMP', '/tmp')
87
- arguments[:path_logs] ||= ENV.fetch('TEST_CLUSTER_LOGS', '/tmp/log/elasticsearch')
88
- arguments[:es_params] ||= ENV.fetch('TEST_CLUSTER_PARAMS', '')
89
- arguments[:multicast_enabled] ||= ENV.fetch('TEST_CLUSTER_MULTICAST', 'true')
90
- arguments[:timeout] ||= (ENV.fetch('TEST_CLUSTER_TIMEOUT', 30).to_i)
91
- arguments[:network_host] ||= @@network_host
92
-
93
- clear_cluster = !!arguments[:clear_cluster] || (ENV.fetch('TEST_CLUSTER_CLEAR', 'true') != 'false')
94
-
95
- # Make sure `cluster_name` is not dangerous
96
- if arguments[:cluster_name] =~ /^[\/\\]?$/
97
- raise ArgumentError, "The `cluster_name` parameter cannot be empty string or a slash"
98
- end
99
-
100
- if running? :on => arguments[:port], :as => arguments[:cluster_name]
101
- print "[!] Elasticsearch cluster already running".ansi(:red)
102
- wait_for_green(arguments[:port], arguments[:timeout])
103
- return false
104
- end
63
+ def wait_for_green(arguments={})
64
+ Cluster.new(arguments).wait_for_green
65
+ end
105
66
 
106
- # Wipe out data on disk for this cluster name by default
107
- FileUtils.rm_rf "#{arguments[:path_data]}/#{arguments[:cluster_name]}" if clear_cluster
67
+ module_function :start, :stop, :running?, :wait_for_green
108
68
 
109
- print "Starting ".ansi(:faint) +
110
- @@number_of_nodes.to_s.ansi(:bold, :faint) +
111
- " Elasticsearch nodes..".ansi(:faint)
69
+ class Cluster
70
+ attr_reader :arguments
112
71
 
113
- pids = []
72
+ COMMANDS = {
73
+ '0.90' => lambda { |arguments, node_number|
74
+ <<-COMMAND.gsub(/ /, '')
75
+ #{arguments[:command]} \
76
+ -f \
77
+ -D es.cluster.name=#{arguments[:cluster_name]} \
78
+ -D es.node.name=#{arguments[:node_name]}-#{node_number} \
79
+ -D es.http.port=#{arguments[:port].to_i + (node_number-1)} \
80
+ -D es.path.data=#{arguments[:path_data]} \
81
+ -D es.path.work=#{arguments[:path_work]} \
82
+ -D es.path.logs=#{arguments[:path_logs]} \
83
+ -D es.cluster.routing.allocation.disk.threshold_enabled=false \
84
+ -D es.network.host=#{arguments[:network_host]} \
85
+ -D es.discovery.zen.ping.multicast.enabled=#{arguments[:multicast_enabled]} \
86
+ -D es.script.inline=true \
87
+ -D es.script.indexed=true \
88
+ -D es.node.test=true \
89
+ -D es.node.testattr=test \
90
+ -D es.node.bench=true \
91
+ -D es.path.repo=/tmp \
92
+ -D es.repositories.url.allowed_urls=http://snapshot.test* \
93
+ -D es.logger.level=DEBUG \
94
+ #{arguments[:es_params]} \
95
+ > /dev/null
96
+ COMMAND
97
+ },
114
98
 
115
- @@number_of_nodes.times do |n|
116
- n += 1
117
- command = <<-COMMAND
118
- #{arguments[:command]} \
99
+ '1.0' => lambda { |arguments, node_number|
100
+ <<-COMMAND.gsub(/ /, '')
101
+ #{arguments[:command]} \
119
102
  -D es.foreground=yes \
120
103
  -D es.cluster.name=#{arguments[:cluster_name]} \
121
- -D es.node.name=#{arguments[:node_name]}-#{n} \
122
- -D es.http.port=#{arguments[:port].to_i + (n-1)} \
104
+ -D es.node.name=#{arguments[:node_name]}-#{node_number} \
105
+ -D es.http.port=#{arguments[:port].to_i + (node_number-1)} \
123
106
  -D es.path.data=#{arguments[:path_data]} \
124
107
  -D es.path.work=#{arguments[:path_work]} \
125
108
  -D es.path.logs=#{arguments[:path_logs]} \
126
109
  -D es.cluster.routing.allocation.disk.threshold_enabled=false \
127
- -D es.network.host=#{@@network_host} \
110
+ -D es.network.host=#{arguments[:network_host]} \
128
111
  -D es.discovery.zen.ping.multicast.enabled=#{arguments[:multicast_enabled]} \
129
112
  -D es.script.inline=on \
130
113
  -D es.script.indexed=on \
@@ -133,196 +116,472 @@ module Elasticsearch
133
116
  -D es.node.bench=true \
134
117
  -D es.path.repo=/tmp \
135
118
  -D es.repositories.url.allowed_urls=http://snapshot.test* \
136
- -D es.logger.level=DEBUG \
119
+ -D es.logger.level=#{ENV['DEBUG'] ? 'DEBUG' : 'INFO'} \
137
120
  #{arguments[:es_params]} \
138
121
  > /dev/null
139
- COMMAND
140
- STDERR.puts command.gsub(/ {1,}/, ' ') if ENV['DEBUG']
122
+ COMMAND
123
+ },
141
124
 
142
- pid = Process.spawn(command)
143
- Process.detach pid
144
- pids << pid
125
+ '2.0' => lambda { |arguments, node_number|
126
+ <<-COMMAND.gsub(/ /, '')
127
+ #{arguments[:command]} \
128
+ -D es.foreground=yes \
129
+ -D es.cluster.name=#{arguments[:cluster_name]} \
130
+ -D es.node.name=#{arguments[:node_name]}-#{node_number} \
131
+ -D es.http.port=#{arguments[:port].to_i + (node_number-1)} \
132
+ -D es.path.data=#{arguments[:path_data]} \
133
+ -D es.path.work=#{arguments[:path_work]} \
134
+ -D es.path.logs=#{arguments[:path_logs]} \
135
+ -D es.cluster.routing.allocation.disk.threshold_enabled=false \
136
+ -D es.network.host=#{arguments[:network_host]} \
137
+ -D es.script.inline=true \
138
+ -D es.script.stored=true \
139
+ -D es.node.attr.testattr=test \
140
+ -D es.path.repo=/tmp \
141
+ -D es.repositories.url.allowed_urls=http://snapshot.test* \
142
+ -D es.logger.level=DEBUG \
143
+ #{arguments[:es_params]} \
144
+ > /dev/null
145
+ COMMAND
146
+ },
147
+
148
+ '5.0' => lambda { |arguments, node_number|
149
+ <<-COMMAND.gsub(/ /, '')
150
+ #{arguments[:command]} \
151
+ -E cluster.name=#{arguments[:cluster_name]} \
152
+ -E node.name=#{arguments[:node_name]}-#{node_number} \
153
+ -E http.port=#{arguments[:port].to_i + (node_number-1)} \
154
+ -E path.data=#{arguments[:path_data]} \
155
+ -E path.logs=#{arguments[:path_logs]} \
156
+ -E cluster.routing.allocation.disk.threshold_enabled=false \
157
+ -E network.host=#{arguments[:network_host]} \
158
+ -E script.inline=true \
159
+ -E script.stored=true \
160
+ -E node.attr.testattr=test \
161
+ -E path.repo=/tmp \
162
+ -E repositories.url.allowed_urls=http://snapshot.test* \
163
+ -E discovery.zen.minimum_master_nodes=#{arguments[:number_of_nodes]-1} \
164
+ -E logger.level=DEBUG \
165
+ #{arguments[:es_params]} \
166
+ > /dev/null
167
+ COMMAND
168
+ }
169
+ }
170
+
171
+ # Create a new instance of the Cluster class
172
+ #
173
+ # @option arguments [String] :cluster_name Cluster name (default: `elasticsearch_test`)
174
+ # @option arguments [Integer] :nodes Number of desired nodes (default: 2)
175
+ # @option arguments [String] :command Elasticsearch command (default: `elasticsearch`)
176
+ # @option arguments [String] :port Starting port number; will be auto-incremented (default: 9250)
177
+ # @option arguments [String] :node_name The node name (will be appended with a number)
178
+ # @option arguments [String] :path_data Path to the directory to store data in
179
+ # @option arguments [String] :path_work Path to the directory with auxiliary files
180
+ # @option arguments [String] :path_logs Path to the directory with log files
181
+ # @option arguments [Boolean] :multicast_enabled Whether multicast is enabled (default: true)
182
+ # @option arguments [Integer] :timeout Timeout when starting the cluster (default: 30)
183
+ # @option arguments [String] :network_host The host that nodes will bind on and publish to
184
+ # @option arguments [Boolean] :clear_cluster Wipe out cluster content on startup (default: true)
185
+ #
186
+ # You can also use environment variables to set the constructor options (see source).
187
+ #
188
+ # @see Cluster#start
189
+ #
190
+ def initialize(arguments={})
191
+ @arguments = arguments
192
+
193
+ @arguments[:command] ||= ENV.fetch('TEST_CLUSTER_COMMAND', 'elasticsearch')
194
+ @arguments[:port] ||= ENV.fetch('TEST_CLUSTER_PORT', 9250).to_i
195
+ @arguments[:cluster_name] ||= ENV.fetch('TEST_CLUSTER_NAME', __default_cluster_name).chomp
196
+ @arguments[:node_name] ||= ENV.fetch('TEST_CLUSTER_NODE_NAME', 'node')
197
+ @arguments[:path_data] ||= ENV.fetch('TEST_CLUSTER_DATA', '/tmp/elasticsearch_test')
198
+ @arguments[:path_work] ||= ENV.fetch('TEST_CLUSTER_TMP', '/tmp')
199
+ @arguments[:path_logs] ||= ENV.fetch('TEST_CLUSTER_LOGS', '/tmp/log/elasticsearch')
200
+ @arguments[:es_params] ||= ENV.fetch('TEST_CLUSTER_PARAMS', '')
201
+ @arguments[:multicast_enabled] ||= ENV.fetch('TEST_CLUSTER_MULTICAST', 'true')
202
+ @arguments[:timeout] ||= ENV.fetch('TEST_CLUSTER_TIMEOUT', 30).to_i
203
+ @arguments[:number_of_nodes] ||= ENV.fetch('TEST_CLUSTER_NODES', 2).to_i
204
+ @arguments[:network_host] ||= ENV.fetch('TEST_CLUSTER_NETWORK_HOST', __default_network_host)
205
+
206
+ @clear_cluster = !!@arguments[:clear_cluster] || (ENV.fetch('TEST_CLUSTER_CLEAR', 'true') != 'false')
207
+
208
+ # Make sure `cluster_name` is not dangerous
209
+ raise ArgumentError, "The `cluster_name` argument cannot be empty string or a slash" \
210
+ if @arguments[:cluster_name] =~ /^[\/\\]?$/
145
211
  end
146
212
 
147
- # Check for proceses running
148
- if `ps -p #{pids.join(' ')}`.split("\n").size < @@number_of_nodes+1
149
- STDERR.puts "", "[!!!] Process failed to start (see output above)".ansi(:red)
150
- exit(1)
151
- end
213
+ # Starts a cluster
214
+ #
215
+ # Launches the specified number of nodes in a test-suitable configuration and prints
216
+ # information about the cluster -- unless this specific cluster is already running.
217
+ #
218
+ # @example Start a cluster with the default configuration (2 nodes, installed version, etc)
219
+ # Elasticsearch::Extensions::Test::Cluster::Cluster.new.start
220
+ #
221
+ # @example Start a cluster with a custom configuration
222
+ # Elasticsearch::Extensions::Test::Cluster::Cluster.new(
223
+ # cluster_name: 'my-cluster',
224
+ # nodes: 3,
225
+ # node_name: 'my-node',
226
+ # port: 9350
227
+ # ).start
228
+ #
229
+ # @example Start a cluster with a different Elasticsearch version
230
+ # Elasticsearch::Extensions::Test::Cluster::Cluster.new(
231
+ # command: "/usr/local/Cellar/elasticsearch/1.0.0.Beta2/bin/elasticsearch"
232
+ # ).start
233
+ #
234
+ # @return Boolean,Array
235
+ # @see Cluster#stop
236
+ #
237
+ def start
238
+ if self.running?
239
+ STDOUT.print "[!] Elasticsearch cluster already running".ansi(:red)
240
+ return false
241
+ end
152
242
 
153
- wait_for_green(arguments[:port], arguments[:timeout])
154
- return true
155
- end
243
+ __remove_cluster_data
156
244
 
157
- # Stop the cluster.
158
- #
159
- # Fetches the PID numbers from "Nodes Info" API and terminates matching nodes.
160
- #
161
- # @example Stop the default cluster
162
- # Elasticsearch::Extensions::Test::Cluster.stop
163
- #
164
- # @example Stop the cluster reachable on specific port
165
- # Elasticsearch::Extensions::Test::Cluster.stop port: 9350
166
- #
167
- # @return Boolean
168
- # @see Cluster#start Cluster.start
169
- #
170
- def stop(arguments={})
171
- arguments[:port] ||= (ENV['TEST_CLUSTER_PORT'] || 9250).to_i
172
- arguments[:network_host] ||= ENV.fetch('TEST_CLUSTER_NETWORK_HOST', @@network_host)
173
-
174
- nodes = begin
175
- JSON.parse(Net::HTTP.get(URI("http://#{arguments[:network_host]}:#{arguments[:port]}/_nodes/?process")))
176
- rescue Exception => e
177
- STDERR.puts "[!] Exception raised when stopping the cluster: #{e.inspect}".ansi(:red)
178
- nil
179
- end
245
+ STDOUT.print "Starting ".ansi(:faint) + arguments[:number_of_nodes].to_s.ansi(:bold, :faint) +
246
+ " Elasticsearch nodes..".ansi(:faint)
247
+ pids = []
180
248
 
181
- return false if nodes.nil? or nodes.empty?
249
+ STDERR.puts "Using Elasticsearch version [#{version}]" if ENV['DEBUG']
182
250
 
183
- pids = nodes['nodes'].map { |id, info| info['process']['id'] }
251
+ arguments[:number_of_nodes].times do |n|
252
+ n += 1
253
+ command = __command(version, arguments, n)
254
+ STDERR.puts command.gsub(/ {1,}/, ' ') if ENV['DEBUG']
184
255
 
185
- unless pids.empty?
186
- print "\nStopping Elasticsearch nodes... ".ansi(:faint)
187
- pids.each_with_index do |pid, i|
188
- ['INT','KILL'].each do |signal|
189
- begin
190
- Process.kill signal, pid
191
- rescue Exception => e
192
- print "[#{e.class}] PID #{pid} not found. ".ansi(:red)
193
- end
256
+ pid = Process.spawn(command)
257
+ Process.detach pid
258
+ pids << pid
259
+ end
194
260
 
195
- # Give the system some breathing space to finish...
196
- sleep 1
261
+ __check_for_running_processes(pids)
262
+ wait_for_green
263
+ __print_cluster_info
264
+
265
+ return true
266
+ end
197
267
 
198
- # Check that pid really is dead
199
- begin
200
- Process.getpgid( pid )
201
- # `getpgid` will raise error if pid is dead, so if we get here, try next signal.
202
- next
203
- rescue Errno::ESRCH
204
- print "stopped PID #{pid} with #{signal} signal. ".ansi(:green)
205
- break # pid is dead
268
+ # Stops the cluster
269
+ #
270
+ # Fetches the PID numbers from "Nodes Info" API and terminates matching nodes.
271
+ #
272
+ # @example Stop the default cluster
273
+ # Elasticsearch::Extensions::Test::Cluster::Cluster.new.stop
274
+ #
275
+ # @example Stop the cluster reachable on specific port
276
+ # Elasticsearch::Extensions::Test::Cluster::Cluster.new(port: 9350).stop
277
+ #
278
+ # @return Boolean,Array
279
+ # @see Cluster#start
280
+ #
281
+ def stop
282
+ begin
283
+ nodes = __get_nodes
284
+ rescue Exception => e
285
+ STDERR.puts "[!] Exception raised when stopping the cluster: #{e.inspect}".ansi(:red)
286
+ nil
287
+ end
288
+
289
+ return false if nodes.nil? or nodes.empty?
290
+
291
+ pids = nodes['nodes'].map { |id, info| info['process']['id'] }
292
+
293
+ unless pids.empty?
294
+ STDOUT.print "\nStopping Elasticsearch nodes... ".ansi(:faint)
295
+ pids.each_with_index do |pid, i|
296
+ ['INT','KILL'].each do |signal|
297
+ begin
298
+ Process.kill signal, pid
299
+ rescue Exception => e
300
+ STDOUT.print "[#{e.class}] PID #{pid} not found. ".ansi(:red)
301
+ end
302
+
303
+ # Give the system some breathing space to finish...
304
+ Kernel.sleep 1
305
+
306
+ # Check that pid really is dead
307
+ begin
308
+ Process.getpgid pid
309
+ # `getpgid` will raise error if pid is dead, so if we get here, try next signal
310
+ next
311
+ rescue Errno::ESRCH
312
+ STDOUT.print "Stopped PID #{pid}".ansi(:green) +
313
+ (ENV['DEBUG'] ? " with #{signal} signal".ansi(:green) : '') +
314
+ ". ".ansi(:green)
315
+ break # pid is dead
316
+ end
206
317
  end
207
318
  end
319
+ STDOUT.puts
320
+ else
321
+ return false
208
322
  end
209
- puts
210
- else
211
- false
323
+
324
+ return pids
212
325
  end
213
326
 
214
- return pids
215
- end
327
+ # Returns true when a specific test node is running within the cluster
328
+ #
329
+ # @return Boolean
330
+ #
331
+ def running?
332
+ if cluster_health = Timeout::timeout(0.25) { __get_cluster_health } rescue nil
333
+ return cluster_health['cluster_name'] == arguments[:cluster_name] && \
334
+ cluster_health['number_of_nodes'] == arguments[:number_of_nodes]
335
+ end
336
+ return false
337
+ end
216
338
 
217
- # Returns true when a specific test node is running within the cluster.
218
- #
219
- # @option arguments [Integer] :on The port on which the node is running.
220
- # @option arguments [String] :as The cluster name.
221
- # @option arguments [Integer] :num Number of nodes in the cluster.
222
- #
223
- # @return Boolean
224
- #
225
- def running?(arguments={})
226
- port = arguments[:on] || (ENV['TEST_CLUSTER_PORT'] || 9250).to_i
227
- cluster_name = arguments[:as] || (ENV.fetch('TEST_CLUSTER_NAME', @@default_cluster_name).chomp)
228
- number_of_nodes = arguments[:num] || (ENV.fetch('TEST_CLUSTER_NODES', @@number_of_nodes)).to_i
339
+ # Waits until the cluster is green and prints information about it
340
+ #
341
+ # @return Boolean
342
+ #
343
+ def wait_for_green
344
+ __wait_for_status('green', 60)
345
+ end
229
346
 
230
- if cluster_health = Timeout::timeout(0.25) { __get_cluster_health(port) } rescue nil
231
- return cluster_health['cluster_name'] == cluster_name && \
232
- cluster_health['number_of_nodes'] == number_of_nodes
347
+ # Returns the major version of Elasticsearch
348
+ #
349
+ # @return String
350
+ # @see __determine_version
351
+ #
352
+ def version
353
+ @version ||= __determine_version
233
354
  end
234
- return false
235
- end
236
355
 
237
- # Waits until the cluster is green and prints information
238
- #
239
- # @example Print the information about the default cluster
240
- # Elasticsearch::Extensions::Test::Cluster.wait_for_green
241
- #
242
- # @param (see #__wait_for_status)
243
- #
244
- # @return Boolean
245
- #
246
- def wait_for_green(port=9250, timeout=60)
247
- __wait_for_status('green', port, timeout)
248
- end
249
356
 
250
- # Blocks the process and waits for the cluster to be in a "green" state.
251
- #
252
- # Prints information about the cluster on STDOUT if the cluster is available.
253
- #
254
- # @param status [String] The status to wait for (yellow, green)
255
- # @param port [Integer] The port on which the cluster is reachable
256
- # @param timeout [Integer] The explicit timeout for the operation
257
- #
258
- # @api private
259
- #
260
- # @return Boolean
261
- #
262
- def __wait_for_status(status='green', port=9250, timeout=30)
263
- uri = URI("http://#{@@network_host}:#{port}/_cluster/health?wait_for_status=#{status}")
264
-
265
- Timeout::timeout(timeout) do
266
- loop do
267
- response = begin
268
- JSON.parse(Net::HTTP.get(uri))
269
- rescue Exception => e
270
- STDERR.puts e.inspect if ENV['DEBUG']
271
- nil
357
+ # Returns default `:network_host` setting based on the version
358
+ #
359
+ # @api private
360
+ #
361
+ # @return String
362
+ #
363
+ def __default_network_host
364
+ case version
365
+ when /^0|^1/
366
+ '0.0.0.0'
367
+ when /^2/
368
+ '0.0.0.0'
369
+ when /^5/
370
+ '_local_'
371
+ else
372
+ raise RuntimeError, "Cannot determine default network host from version [#{version}]"
373
+ end
374
+ end
375
+
376
+ # Returns a reasonably unique cluster name
377
+ #
378
+ # @api private
379
+ #
380
+ # @return String
381
+ #
382
+ def __default_cluster_name
383
+ "elasticsearch-test-#{Socket.gethostname.downcase}"
384
+ end
385
+
386
+ # Returns the HTTP URL for the cluster based on `:network_host` setting
387
+ #
388
+ # @api private
389
+ #
390
+ # @return String
391
+ #
392
+ def __cluster_url
393
+ if '_local_' == arguments[:network_host]
394
+ "http://localhost:#{arguments[:port]}"
395
+ else
396
+ "http://#{arguments[:network_host]}:#{arguments[:port]}"
397
+ end
398
+ end
399
+
400
+ # Determine Elasticsearch version to be launched
401
+ #
402
+ # Tries to parse the version number from the `lib/elasticsearch-X.Y.Z.jar` file,
403
+ # it not available, uses `elasticsearch --version` or `elasticsearch -v`
404
+ #
405
+ # @api private
406
+ #
407
+ # @return String
408
+ #
409
+ def __determine_version
410
+ path_to_lib = File.dirname(arguments[:command]) + '/../lib/'
411
+
412
+ jar = Dir.entries(path_to_lib).select { |f| f.start_with? 'elasticsearch' }.first if File.exist? path_to_lib
413
+
414
+ version = if jar
415
+ if m = jar.match(/elasticsearch\-(\d+\.\d+.\d+).*/)
416
+ m[1]
417
+ else
418
+ raise RuntimeError, "Cannot determine Elasticsearch version from jar [#{jar}]"
419
+ end
420
+ else
421
+ STDERR.puts "[!] Cannot find Elasticsearch .jar from path to command [#{arguments[:command]}], using `elasticsearch --version`" if ENV['DEBUG']
422
+
423
+ output = ''
424
+
425
+ begin
426
+ # First, try the new `--version` syntax...
427
+ STDERR.puts "Running [#{arguments[:command]} --version] to determine version" if ENV['DEBUG']
428
+ Timeout::timeout(10) { output = `#{arguments[:command]} --version` }
429
+ rescue Timeout::Error
430
+ # ...else, the new `-v` syntax
431
+ STDERR.puts "Running [#{arguments[:command]} -v] to determine version" if ENV['DEBUG']
432
+ output = `#{arguments[:command]} -v`
433
+ end
434
+
435
+ STDERR.puts "> #{output}" if ENV['DEBUG']
436
+
437
+ if output.empty?
438
+ raise RuntimeError, "Cannot determine Elasticsearch version from [#{arguments[:command]} --version] or [#{arguments[:command]} -v]"
439
+ end
440
+
441
+ if m = output.match(/Version: (\d\.\d.\d).*,/)
442
+ m[1]
443
+ else
444
+ raise RuntimeError, "Cannot determine Elasticsearch version from elasticsearch --version output [#{output}]"
272
445
  end
446
+ end
447
+
448
+ case version
449
+ when /^0\.90.*/
450
+ '0.90'
451
+ when /^1\..*/
452
+ '1.0'
453
+ when /^2\..*/
454
+ '2.0'
455
+ when /^5\..*/
456
+ '5.0'
457
+ else
458
+ raise RuntimeError, "Cannot determine major version from [#{version}]"
459
+ end
460
+ end
273
461
 
274
- STDERR.puts response.inspect if response && ENV['DEBUG']
462
+ # Returns the launch command for a specific version
463
+ #
464
+ # @api private
465
+ #
466
+ # @return String
467
+ #
468
+ def __command(version, arguments, node_number)
469
+ if command = COMMANDS[version]
470
+ command.call(arguments, node_number)
471
+ else
472
+ raise ArgumentError, "Cannot find command for version [#{version}]"
473
+ end
474
+ end
475
+
476
+ # Blocks the process and waits for the cluster to be in a "green" state
477
+ #
478
+ # Prints information about the cluster on STDOUT if the cluster is available.
479
+ #
480
+ # @param status [String] The status to wait for (yellow, green)
481
+ # @param timeout [Integer] The explicit timeout for the operation
482
+ #
483
+ # @api private
484
+ #
485
+ # @return Boolean
486
+ #
487
+ def __wait_for_status(status='green', timeout=30)
488
+ Timeout::timeout(timeout) do
489
+ loop do
490
+ response = __get_cluster_health(status)
491
+
492
+ if response && response['status'] == status && ( arguments[:number_of_nodes].nil? || arguments[:number_of_nodes].to_i == response['number_of_nodes'].to_i )
493
+ break
494
+ end
275
495
 
276
- if response && response['status'] == status && ( @@number_of_nodes.nil? || @@number_of_nodes == response['number_of_nodes'].to_i )
277
- __print_cluster_info(port) and break
496
+ STDOUT.print '.'.ansi(:faint)
497
+ sleep 1
278
498
  end
499
+ end
500
+
501
+ return true
502
+ end
279
503
 
280
- print '.'.ansi(:faint)
281
- sleep 1
504
+ # Print information about the cluster on STDOUT
505
+ #
506
+ # @api private
507
+ #
508
+ # @return Nil
509
+ #
510
+ def __print_cluster_info
511
+ health = JSON.parse(Net::HTTP.get(URI("#{__cluster_url}/_cluster/health")))
512
+ nodes = if version == '0.90'
513
+ JSON.parse(Net::HTTP.get(URI("#{__cluster_url}/_nodes/?process&http")))
514
+ else
515
+ JSON.parse(Net::HTTP.get(URI("#{__cluster_url}/_nodes/process,http")))
516
+ end
517
+ master = JSON.parse(Net::HTTP.get(URI("#{__cluster_url}/_cluster/state")))['master_node']
518
+
519
+ puts "\n",
520
+ ('-'*80).ansi(:faint),
521
+ 'Cluster: '.ljust(20).ansi(:faint) + health['cluster_name'].to_s.ansi(:faint),
522
+ 'Status: '.ljust(20).ansi(:faint) + health['status'].to_s.ansi(:faint),
523
+ 'Nodes: '.ljust(20).ansi(:faint) + health['number_of_nodes'].to_s.ansi(:faint)
524
+
525
+ nodes['nodes'].each do |id, info|
526
+ m = id == master ? '*' : '+'
527
+ puts ''.ljust(20) +
528
+ "#{m} ".ansi(:faint) +
529
+ "#{info['name'].ansi(:bold)} ".ansi(:faint) +
530
+ "| version: #{info['version'] rescue 'N/A'}, ".ansi(:faint) +
531
+ "pid: #{info['process']['id'] rescue 'N/A'}, ".ansi(:faint) +
532
+ "address: #{info['http']['bound_address'] rescue 'N/A'}".ansi(:faint)
282
533
  end
283
534
  end
284
535
 
285
- return true
286
- end
536
+ # Tries to load cluster health information
537
+ #
538
+ # @api private
539
+ #
540
+ # @return Hash,Nil
541
+ #
542
+ def __get_cluster_health(status=nil)
543
+ uri = URI("#{__cluster_url}/_cluster/health")
544
+ uri.query = "wait_for_status=#{status}" if status
545
+
546
+ begin
547
+ response = Net::HTTP.get(uri)
548
+ rescue Exception => e
549
+ STDERR.puts e.inspect if ENV['DEBUG']
550
+ return nil
551
+ end
287
552
 
288
- # Print information about the cluster on STDOUT
289
- #
290
- # @api private
291
- #
292
- def __print_cluster_info(port)
293
- health = JSON.parse(Net::HTTP.get(URI("http://#{@@network_host}:#{port}/_cluster/health")))
294
- nodes = JSON.parse(Net::HTTP.get(URI("http://#{@@network_host}:#{port}/_nodes/process,http")))
295
- master = JSON.parse(Net::HTTP.get(URI("http://#{@@network_host}:#{port}/_cluster/state")))['master_node']
296
-
297
- puts "\n",
298
- ('-'*80).ansi(:faint),
299
- 'Cluster: '.ljust(20).ansi(:faint) + health['cluster_name'].to_s.ansi(:faint),
300
- 'Status: '.ljust(20).ansi(:faint) + health['status'].to_s.ansi(:faint),
301
- 'Nodes: '.ljust(20).ansi(:faint) + health['number_of_nodes'].to_s.ansi(:faint)
302
-
303
- nodes['nodes'].each do |id, info|
304
- m = id == master ? '*' : '+'
305
- puts ''.ljust(20) +
306
- "#{m} ".ansi(:faint) +
307
- "#{info['name'].ansi(:bold)} ".ansi(:faint) +
308
- "| version: #{info['version'] rescue 'N/A'}, ".ansi(:faint) +
309
- "pid: #{info['process']['id'] rescue 'N/A'}, ".ansi(:faint) +
310
- "address: #{info['http']['bound_address'] rescue 'N/A'}".ansi(:faint)
553
+ JSON.parse(response)
311
554
  end
312
- end
313
555
 
314
- # Tries to load cluster health information
315
- #
316
- # @api private
317
- #
318
- def __get_cluster_health(port=9250)
319
- uri = URI("http://#{@@network_host}:#{port}/_cluster/health")
320
- if response = Net::HTTP.get(uri) rescue nil
321
- return JSON.parse(response)
556
+ # Remove the data directory (unless it has been disabled by arguments)
557
+ #
558
+ # @api private
559
+ #
560
+ def __remove_cluster_data
561
+ # Wipe out data on disk for this cluster name by default
562
+ FileUtils.rm_rf "#{arguments[:path_data]}/#{arguments[:cluster_name]}" if @clear_cluster
322
563
  end
323
- end
324
564
 
325
- extend self
565
+
566
+ # Check whether process for PIDs are running
567
+ #
568
+ # @api private
569
+ #
570
+ def __check_for_running_processes(pids)
571
+ if `ps -p #{pids.join(' ')}`.split("\n").size < arguments[:number_of_nodes]+1
572
+ STDERR.puts "", "[!!!] Process failed to start (see output above)".ansi(:red)
573
+ exit(1)
574
+ end
575
+ end
576
+
577
+ # Get the information about nodes
578
+ #
579
+ # @api private
580
+ #
581
+ def __get_nodes
582
+ JSON.parse(Net::HTTP.get(URI("#{__cluster_url}/_nodes/process")))
583
+ end
584
+ end
326
585
  end
327
586
  end
328
587
  end
@@ -1,5 +1,5 @@
1
1
  module Elasticsearch
2
2
  module Extensions
3
- VERSION = "0.0.21"
3
+ VERSION = "0.0.22"
4
4
  end
5
5
  end
@@ -0,0 +1,29 @@
1
+ require 'test_helper'
2
+ require 'pathname'
3
+
4
+ require 'elasticsearch/extensions/test/cluster'
5
+
6
+ class Elasticsearch::Extensions::TestClusterIntegrationTest < Test::Unit::TestCase
7
+ context "The Test::Cluster" do
8
+ PATH_TO_BUILDS = Pathname(File.expand_path('../../../../../../tmp/builds', __FILE__))
9
+
10
+ unless PATH_TO_BUILDS.exist?
11
+ puts "Path to builds doesn't exist, skipping TestClusterIntegrationTest"
12
+ exit(0)
13
+ end
14
+
15
+ @builds = begin
16
+ PATH_TO_BUILDS.entries.reject { |f| f.to_s =~ /^\./ }
17
+ rescue Errno::ENOENT
18
+ []
19
+ end
20
+
21
+ @builds.each do |build|
22
+ should "start and stop #{build.to_s}" do
23
+ puts ("----- #{build.to_s} " + "-"*(80-7-build.to_s.size)).to_s.ansi(:bold)
24
+ Elasticsearch::Extensions::Test::Cluster.start command: PATH_TO_BUILDS.join(build.join('bin/elasticsearch')).to_s
25
+ Elasticsearch::Extensions::Test::Cluster.stop command: PATH_TO_BUILDS.join(build.join('bin/elasticsearch')).to_s
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,280 @@
1
+ require 'test_helper'
2
+
3
+ require 'elasticsearch/extensions/test/cluster'
4
+
5
+ class Elasticsearch::Extensions::TestClusterTest < Test::Unit::TestCase
6
+ include Elasticsearch::Extensions::Test
7
+ context "The Test::Cluster" do
8
+ context "module" do
9
+ should "delegate the methods to the class" do
10
+ Cluster::Cluster
11
+ .expects(:new)
12
+ .with({foo: 'bar'})
13
+ .returns(mock start: true, stop: true, running?: true, wait_for_green: true)
14
+ .times(4)
15
+
16
+ Elasticsearch::Extensions::Test::Cluster.start foo: 'bar'
17
+ Elasticsearch::Extensions::Test::Cluster.stop foo: 'bar'
18
+ Elasticsearch::Extensions::Test::Cluster.running? foo: 'bar'
19
+ Elasticsearch::Extensions::Test::Cluster.wait_for_green foo: 'bar'
20
+ end
21
+ end
22
+
23
+ context "class" do
24
+ setup do
25
+ Elasticsearch::Extensions::Test::Cluster::Cluster.any_instance.stubs(:__default_network_host).returns('_local_')
26
+
27
+ @subject = Elasticsearch::Extensions::Test::Cluster::Cluster.new
28
+ @subject.stubs(:__remove_cluster_data).returns(true)
29
+ end
30
+
31
+ teardown do
32
+ ENV.delete('TEST_CLUSTER_PORT')
33
+ end
34
+
35
+ should "be initialized with parameters" do
36
+ c = Cluster::Cluster.new port: 9400
37
+
38
+ assert_equal 9400, c.arguments[:port]
39
+ end
40
+
41
+ should "take parameters from environment variables" do
42
+ ENV['TEST_CLUSTER_PORT'] = '9400'
43
+
44
+ c = Cluster::Cluster.new
45
+
46
+ assert_equal 9400, c.arguments[:port]
47
+ end
48
+
49
+ should "raise exception for dangerous cluster name" do
50
+ assert_raise(ArgumentError) { Cluster::Cluster.new cluster_name: '' }
51
+ assert_raise(ArgumentError) { Cluster::Cluster.new cluster_name: '/' }
52
+ end
53
+
54
+ should "have a version" do
55
+ @subject.unstub(:version)
56
+ @subject.expects(:__determine_version).returns('2.0')
57
+ assert_equal '2.0', @subject.version
58
+ end
59
+
60
+ should "have a default network host" do
61
+ Cluster::Cluster.any_instance.unstub(:__default_network_host)
62
+ Cluster::Cluster.any_instance.stubs(:version).returns('5.0')
63
+
64
+ assert_equal '_local_', Cluster::Cluster.new.__default_network_host
65
+ end
66
+
67
+ should "have a default cluster name" do
68
+ Socket.stubs(:gethostname).returns('FOOBAR')
69
+
70
+ assert_equal 'elasticsearch-test-foobar', Cluster::Cluster.new.__default_cluster_name
71
+ end
72
+
73
+ should "have a cluster URL for new versions" do
74
+ assert_equal 'http://localhost:9250', Cluster::Cluster.new(network_host: '_local_').__cluster_url
75
+ end
76
+
77
+ should "have a cluster URL for old versions" do
78
+ assert_equal 'http://192.168.1.1:9250', Cluster::Cluster.new(network_host: '192.168.1.1').__cluster_url
79
+ end
80
+
81
+ should "return corresponding command to a version" do
82
+ assert_match /\-D es\.foreground=yes/, @subject.__command('2.0', @subject.arguments, 1)
83
+ end
84
+
85
+ should "raise an error when a corresponding command cannot be found" do
86
+ assert_raise ArgumentError do
87
+ @subject.__command('FOOBAR', @subject.arguments, 1)
88
+ end
89
+ end
90
+
91
+ context "when starting a cluster, " do
92
+ should "return false when it's already running" do
93
+ Process.expects(:spawn).never
94
+
95
+ c = Cluster::Cluster.new
96
+
97
+ c.expects(:running?).returns(true)
98
+
99
+ assert_equal false, c.start
100
+ end
101
+
102
+ should "start the specified number of nodes" do
103
+ Process.expects(:spawn).times(3)
104
+ Process.expects(:detach).times(3)
105
+
106
+ c = Cluster::Cluster.new number_of_nodes: 3
107
+
108
+ c.expects(:running?).returns(false)
109
+
110
+ c.unstub(:__remove_cluster_data)
111
+ c.expects(:__remove_cluster_data).returns(true)
112
+
113
+ c.expects(:wait_for_green).returns(true)
114
+ c.expects(:__check_for_running_processes).returns(true)
115
+ c.expects(:__determine_version).returns('5.0')
116
+ c.expects(:__print_cluster_info).returns(true)
117
+
118
+ assert_equal true, c.start
119
+ end
120
+ end
121
+
122
+ context "when stopping a cluster" do
123
+ setup do
124
+ @subject = Elasticsearch::Extensions::Test::Cluster::Cluster.new
125
+ end
126
+
127
+ should "print information about an exception" do
128
+ @subject.expects(:__get_nodes).raises(Errno::ECONNREFUSED)
129
+
130
+ assert_nothing_raised do
131
+ assert_equal false, @subject.stop
132
+ end
133
+ end
134
+
135
+ should "return false when the nodes are empty" do
136
+ @subject.expects(:__get_nodes).returns({})
137
+ assert_equal false, @subject.stop
138
+ end
139
+
140
+ should "kill each node" do
141
+ @subject.expects(:__get_nodes).returns({'nodes' => { 'n1' => { 'process' => { 'id' => 1 }},
142
+ 'n2' => { 'process' => { 'id' => 2 }} }})
143
+
144
+ Kernel.stubs(:sleep)
145
+ Process.expects(:kill).with('INT', 1)
146
+ Process.expects(:kill).with('INT', 2)
147
+ Process.expects(:getpgid).with(1).raises(Errno::ESRCH)
148
+ Process.expects(:getpgid).with(2).raises(Errno::ESRCH)
149
+
150
+ assert_equal [1, 2], @subject.stop
151
+ end
152
+ end
153
+
154
+ context "when checking if the cluster is running" do
155
+ setup do
156
+ @subject = Elasticsearch::Extensions::Test::Cluster::Cluster.new \
157
+ cluster_name: 'test',
158
+ number_of_nodes: 2
159
+ end
160
+
161
+ should "return true" do
162
+ @subject.expects(:__get_cluster_health).returns({'cluster_name' => 'test', 'number_of_nodes' => 2})
163
+ assert_equal true, @subject.running?
164
+ end
165
+
166
+ should "return false" do
167
+ @subject.expects(:__get_cluster_health).returns({'cluster_name' => 'test', 'number_of_nodes' => 1})
168
+ assert_equal false, @subject.running?
169
+ end
170
+ end
171
+
172
+ context "when waiting for the green state" do
173
+ should "return true" do
174
+ @subject.expects(:__wait_for_status).returns(true)
175
+ assert_equal true, @subject.wait_for_green
176
+ end
177
+ end
178
+
179
+ context "when waiting for cluster state" do
180
+ setup do
181
+ @subject = Elasticsearch::Extensions::Test::Cluster::Cluster.new \
182
+ cluster_name: 'test',
183
+ number_of_nodes: 1
184
+ end
185
+
186
+ should "return true" do
187
+ @subject.stubs(:__print_cluster_info)
188
+
189
+ @subject
190
+ .expects(:__get_cluster_health)
191
+ .with('yellow')
192
+ .returns({'status' => 'yellow', 'cluster_name' => 'test', 'number_of_nodes' => 1})
193
+
194
+ @subject.__wait_for_status('yellow')
195
+ end
196
+ end
197
+
198
+ context "when getting the cluster health" do
199
+ should "return the response" do
200
+ Net::HTTP
201
+ .expects(:get)
202
+ .with(URI('http://localhost:9250/_cluster/health'))
203
+ .returns(JSON.dump({'status' => 'yellow', 'cluster_name' => 'test', 'number_of_nodes' => 1}))
204
+
205
+ @subject.__get_cluster_health
206
+ end
207
+
208
+ should "wait for status" do
209
+ Net::HTTP
210
+ .expects(:get)
211
+ .with(URI('http://localhost:9250/_cluster/health?wait_for_status=green'))
212
+ .returns(JSON.dump({'status' => 'yellow', 'cluster_name' => 'test', 'number_of_nodes' => 1}))
213
+
214
+ @subject.__get_cluster_health('green')
215
+ end
216
+ end
217
+
218
+ context "when getting the list of nodes" do
219
+ should "return the response" do
220
+ Net::HTTP
221
+ .expects(:get)
222
+ .with(URI('http://localhost:9250/_nodes/process'))
223
+ .returns(JSON.dump({'nodes' => { 'n1' => {}, 'n2' => {} } }))
224
+
225
+ assert_equal 'n1', @subject.__get_nodes['nodes'].keys.first
226
+ end
227
+ end
228
+
229
+ context "when determining a version" do
230
+ setup do
231
+ @subject = Elasticsearch::Extensions::Test::Cluster::Cluster.new command: '/foo/bar/bin/elasticsearch'
232
+ end
233
+
234
+ should "return version from lib/elasticsearch.X.Y.Z.jar" do
235
+ File.expects(:exist?).with('/foo/bar/bin/../lib/').returns(true)
236
+ Dir.expects(:entries).with('/foo/bar/bin/../lib/').returns(['foo.jar', 'elasticsearch-2.3.0.jar'])
237
+
238
+ assert_equal '2.0', @subject.__determine_version
239
+ end
240
+
241
+ should "return version from `elasticsearch -v`" do
242
+ File.expects(:exist?).with('/foo/bar/bin/../lib/').returns(false)
243
+
244
+ @subject.expects(:`)
245
+ .with("/foo/bar/bin/elasticsearch --version")
246
+ .returns('Version: 2.3.0-SNAPSHOT, Build: d1c86b0/2016-03-30T10:43:20Z, JVM: 1.8.0_60')
247
+
248
+ assert_equal '2.0', @subject.__determine_version
249
+ end
250
+
251
+ should "raise an exception when the version cannot be parsed from .jar" do
252
+ # Incorrect jar version
253
+ File.expects(:exist?).with('/foo/bar/bin/../lib/').returns(true)
254
+ Dir.expects(:entries).with('/foo/bar/bin/../lib/').returns(['elasticsearch-100.jar'])
255
+
256
+ assert_raise(RuntimeError) { @subject.__determine_version }
257
+ end
258
+
259
+ should "raise an exception when the version cannot be parsed from command output" do
260
+ File.expects(:exist?).with('/foo/bar/bin/../lib/').returns(false)
261
+
262
+ @subject.expects(:`)
263
+ .with("/foo/bar/bin/elasticsearch --version")
264
+ .returns('Version: FOOBAR')
265
+
266
+ assert_raise(RuntimeError) { @subject.__determine_version }
267
+ end
268
+
269
+ should "raise an exception when the version cannot be converted to short version" do
270
+ # There's no Elasticsearch version 3...
271
+ File.expects(:exist?).with('/foo/bar/bin/../lib/').returns(true)
272
+ Dir.expects(:entries).with('/foo/bar/bin/../lib/').returns(['elasticsearch-3.2.1.jar'])
273
+
274
+ assert_raise(RuntimeError) { @subject.__determine_version }
275
+ end
276
+ end
277
+ end
278
+
279
+ end
280
+ end
@@ -8,7 +8,7 @@ end
8
8
 
9
9
  if ENV['COVERAGE'] && ENV['CI'].nil? && !RUBY_1_8
10
10
  require 'simplecov'
11
- SimpleCov.start { add_filter "/test|test_/" }
11
+ SimpleCov.start { add_filter "test_" }
12
12
  end
13
13
 
14
14
  if ENV['CI'] && !RUBY_1_8
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticsearch-extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.21
4
+ version: 0.0.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karel Minarik
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-30 00:00:00.000000000 Z
11
+ date: 2016-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ansi
@@ -278,6 +278,8 @@ files:
278
278
  - test/backup/unit/backup_test.rb
279
279
  - test/reindex/integration/reindex_test.rb
280
280
  - test/reindex/unit/reindex_test.rb
281
+ - test/test/cluster/integration/cluster_test.rb
282
+ - test/test/cluster/unit/cluster_test.rb
281
283
  - test/test_helper.rb
282
284
  homepage: ''
283
285
  licenses:
@@ -308,5 +310,7 @@ test_files:
308
310
  - test/backup/unit/backup_test.rb
309
311
  - test/reindex/integration/reindex_test.rb
310
312
  - test/reindex/unit/reindex_test.rb
313
+ - test/test/cluster/integration/cluster_test.rb
314
+ - test/test/cluster/unit/cluster_test.rb
311
315
  - test/test_helper.rb
312
316
  has_rdoc: