elasticsnap 0.1.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 +7 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/.travis.yml +17 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +192 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bin/elasticsnap +7 -0
- data/elasticsnap.gemspec +31 -0
- data/lib/elasticsnap.rb +5 -0
- data/lib/elasticsnap/cli.rb +2 -0
- data/lib/elasticsnap/cli/application.rb +33 -0
- data/lib/elasticsnap/cli/base.rb +18 -0
- data/lib/elasticsnap/config.rb +24 -0
- data/lib/elasticsnap/ebs_snapshot.rb +30 -0
- data/lib/elasticsnap/freeze_elasticsearch.rb +72 -0
- data/lib/elasticsnap/freeze_fs.rb +55 -0
- data/lib/elasticsnap/security_group.rb +50 -0
- data/lib/elasticsnap/snapshot.rb +56 -0
- data/lib/elasticsnap/snapshot_volume_tags.rb +13 -0
- data/lib/elasticsnap/verify_es_cluster_status.rb +42 -0
- data/lib/elasticsnap/version.rb +3 -0
- data/spec/acceptance/snapshot_spec.rb +75 -0
- data/spec/elasticsnap/ebs_snapshot_spec.rb +63 -0
- data/spec/elasticsnap/freeze_elasticsearch_spec.rb +102 -0
- data/spec/elasticsnap/freeze_fs_spec.rb +54 -0
- data/spec/elasticsnap/security_group_spec.rb +81 -0
- data/spec/elasticsnap/snapshot_spec.rb +63 -0
- data/spec/elasticsnap/verify_es_cluster_status_spec.rb +32 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/support/aruba.rb +26 -0
- metadata +225 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module Elasticsnap
|
|
2
|
+
class FreezeElasticsearch
|
|
3
|
+
class Error < StandardError; end
|
|
4
|
+
class FlushFailed < Error; end
|
|
5
|
+
class DisableFlushFailed < Error; end
|
|
6
|
+
class EnableFlushFailed < Error; end
|
|
7
|
+
|
|
8
|
+
attr_accessor :url
|
|
9
|
+
|
|
10
|
+
def initialize(url: nil)
|
|
11
|
+
raise ArgumentError, 'url required' if url.nil?
|
|
12
|
+
|
|
13
|
+
@url = url
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def freeze(&block)
|
|
17
|
+
begin
|
|
18
|
+
flush
|
|
19
|
+
disable_flush
|
|
20
|
+
|
|
21
|
+
block.call unless block.nil?
|
|
22
|
+
ensure
|
|
23
|
+
enable_flush
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def flush
|
|
28
|
+
Flex::Configuration.http_client.base_uri = url
|
|
29
|
+
result = Flex.flush_index(index: '_all')
|
|
30
|
+
|
|
31
|
+
raise FlushFailed unless result.fetch('ok', false) == true
|
|
32
|
+
|
|
33
|
+
result
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def disable_flush
|
|
37
|
+
Flex::Configuration.http_client.base_uri = url
|
|
38
|
+
result = Flex.update_index_settings(
|
|
39
|
+
index: '_all',
|
|
40
|
+
data: {
|
|
41
|
+
index: {
|
|
42
|
+
translog: {
|
|
43
|
+
disable_flush: true
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
raise DisableFlushFailed unless result.fetch('ok', false) == true
|
|
50
|
+
|
|
51
|
+
result
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def enable_flush
|
|
55
|
+
Flex::Configuration.http_client.base_uri = url
|
|
56
|
+
result = Flex.update_index_settings(
|
|
57
|
+
index: '_all',
|
|
58
|
+
data: {
|
|
59
|
+
index: {
|
|
60
|
+
translog: {
|
|
61
|
+
disable_flush: false
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
raise EnableFlushFailed unless result.fetch('ok', false) == true
|
|
68
|
+
|
|
69
|
+
result
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'capistrano/cli'
|
|
2
|
+
|
|
3
|
+
module Elasticsnap
|
|
4
|
+
class FreezeFs
|
|
5
|
+
attr_accessor :mount
|
|
6
|
+
attr_accessor :security_group
|
|
7
|
+
attr_accessor :ssh_user
|
|
8
|
+
|
|
9
|
+
def initialize(mount: nil, security_group: nil, ssh_user: nil)
|
|
10
|
+
raise ArgumentError, 'mount required' if mount.nil?
|
|
11
|
+
raise ArgumentError, 'security_group required' if security_group.nil?
|
|
12
|
+
|
|
13
|
+
@mount = mount
|
|
14
|
+
@security_group = security_group
|
|
15
|
+
@ssh_user = ssh_user
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def freeze(&block)
|
|
19
|
+
begin
|
|
20
|
+
sync
|
|
21
|
+
freeze_fs
|
|
22
|
+
|
|
23
|
+
block.call unless block.nil?
|
|
24
|
+
ensure
|
|
25
|
+
unfreeze_fs
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def sync
|
|
30
|
+
run_command('sudo sync')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def freeze_fs
|
|
34
|
+
run_command 'sudo fsfreeze', '-f', mount
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def unfreeze_fs
|
|
38
|
+
run_command 'sudo fsfreeze', '-u', mount
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
def run_command(*command)
|
|
43
|
+
stream(*command)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def stream(*command)
|
|
47
|
+
command = [command].flatten.join(' ')
|
|
48
|
+
capistrano_config.stream(command, hosts: SecurityGroup.new(name: security_group).ssh_hosts(ssh_user: ssh_user))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def capistrano_config
|
|
52
|
+
@cap_config ||= Capistrano::Configuration.new
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'elasticsnap/config'
|
|
2
|
+
|
|
3
|
+
module Elasticsnap
|
|
4
|
+
class SecurityGroup
|
|
5
|
+
attr_accessor :name
|
|
6
|
+
|
|
7
|
+
def initialize(name: nil)
|
|
8
|
+
raise ArgumentError, 'name required' if name.nil?
|
|
9
|
+
|
|
10
|
+
@name = name
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def hosts
|
|
14
|
+
@hosts ||= connection.servers.all('group-id' => id)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def ssh_hosts(ssh_user: nil)
|
|
18
|
+
hosts.map do |host|
|
|
19
|
+
if ssh_user
|
|
20
|
+
"#{ssh_user}@#{host.dns_name}"
|
|
21
|
+
else
|
|
22
|
+
host.dns_name
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def volumes(cluster_name: nil)
|
|
28
|
+
filters = { 'attachment.instance-id' => hosts.map(&:id) }
|
|
29
|
+
filters.merge!('tag:ClusterName' => cluster_name) if cluster_name
|
|
30
|
+
connection.volumes.all(filters)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def fog_group
|
|
34
|
+
@fog_group ||= connection.security_groups.all('group-name' => name).first
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def id
|
|
38
|
+
@id ||= fog_group.group_id
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def reload
|
|
42
|
+
@hosts = @id = nil
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
def connection
|
|
47
|
+
Config.fog_connection
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'elasticsnap/verify_es_cluster_status'
|
|
2
|
+
require 'elasticsnap/freeze_elasticsearch'
|
|
3
|
+
require 'elasticsnap/freeze_fs'
|
|
4
|
+
require 'elasticsnap/ebs_snapshot'
|
|
5
|
+
|
|
6
|
+
module Elasticsnap
|
|
7
|
+
class Snapshot
|
|
8
|
+
attr_accessor :security_group
|
|
9
|
+
attr_accessor :url
|
|
10
|
+
attr_accessor :mount
|
|
11
|
+
attr_accessor :quorum_nodes
|
|
12
|
+
attr_accessor :wait_timeout
|
|
13
|
+
attr_accessor :cluster_name
|
|
14
|
+
attr_accessor :ssh_user
|
|
15
|
+
|
|
16
|
+
def initialize(security_group: nil, url: nil, mount: nil, quorum_nodes: nil, wait_timeout: 30, cluster_name: nil, ssh_user: nil)
|
|
17
|
+
raise ArgumentError, "security_group required" if security_group.nil?
|
|
18
|
+
raise ArgumentError, "url required" if url.nil?
|
|
19
|
+
raise ArgumentError, "mount required" if mount.nil?
|
|
20
|
+
raise ArgumentError, "quorum_nodes required" if quorum_nodes.nil?
|
|
21
|
+
|
|
22
|
+
@security_group = security_group
|
|
23
|
+
@url = url
|
|
24
|
+
@mount = mount
|
|
25
|
+
@quorum_nodes = quorum_nodes
|
|
26
|
+
@wait_timeout = wait_timeout
|
|
27
|
+
@cluster_name = cluster_name
|
|
28
|
+
@ssh_user = ssh_user
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def call
|
|
32
|
+
verify_es_cluster_status!
|
|
33
|
+
freeze_es do
|
|
34
|
+
freeze_fs do
|
|
35
|
+
ebs_snapshot!
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def verify_es_cluster_status!
|
|
41
|
+
VerifyEsClusterStatus.new(url: url, quorum_nodes: quorum_nodes, wait_timeout: wait_timeout).verify!
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def freeze_es(&block)
|
|
45
|
+
FreezeElasticsearch.new(url: url).freeze(&block)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def freeze_fs(&block)
|
|
49
|
+
FreezeFs.new(mount: mount, security_group: security_group, ssh_user: ssh_user).freeze(&block)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def ebs_snapshot!
|
|
53
|
+
EbsSnapshot.new(security_group: security_group, cluster_name: cluster_name).snapshot
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'flex'
|
|
2
|
+
|
|
3
|
+
module Elasticsnap
|
|
4
|
+
class VerifyEsClusterStatus
|
|
5
|
+
class Error < StandardError; end
|
|
6
|
+
class StatusRed < Error; end
|
|
7
|
+
class NoQuorum < Error; end
|
|
8
|
+
|
|
9
|
+
attr_accessor :url
|
|
10
|
+
attr_accessor :quorum_nodes
|
|
11
|
+
attr_accessor :wait_timeout
|
|
12
|
+
|
|
13
|
+
def initialize(url: nil, quorum_nodes: nil, wait_timeout: 30)
|
|
14
|
+
raise ArgumentError, 'url required' if url.nil?
|
|
15
|
+
raise ArgumentError, 'quorum_nodes required' if quorum_nodes.nil?
|
|
16
|
+
|
|
17
|
+
@url = url
|
|
18
|
+
@quorum_nodes = quorum_nodes
|
|
19
|
+
@wait_timeout = wait_timeout
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def verify!
|
|
23
|
+
wait_for_green_quorum!
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def wait_for_green_quorum!
|
|
27
|
+
Flex::Configuration.http_client.base_uri = url
|
|
28
|
+
health = Flex.cluster_health(
|
|
29
|
+
params: {
|
|
30
|
+
wait_for_status: 'yellow',
|
|
31
|
+
wait_for_nodes: "gt(#{quorum_nodes})",
|
|
32
|
+
timeout: "#{wait_timeout}s"
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
raise StatusRed if health['status'] == 'red'
|
|
37
|
+
raise NoQuorum if health['number_of_nodes'] < quorum_nodes
|
|
38
|
+
|
|
39
|
+
health
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Snapshots' do
|
|
4
|
+
before do
|
|
5
|
+
WebMock.disable_net_connect!
|
|
6
|
+
#WebMock.allow_net_connect!
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
let(:timeout) { 2 }
|
|
10
|
+
let(:quorum) { 2 }
|
|
11
|
+
let(:args) { "-u localhost:9200 -v /dev/sda -q #{quorum} -t #{timeout}" }
|
|
12
|
+
|
|
13
|
+
it 'User creates snapshot' do
|
|
14
|
+
pending 'Add stubs for ssh connections and fog'
|
|
15
|
+
health_check = stub_request(:get, 'localhost:9200/_cluster/health/').with(
|
|
16
|
+
query: hash_including({
|
|
17
|
+
wait_for_nodes: "gt(#{quorum})",
|
|
18
|
+
wait_for_status: 'yellow'
|
|
19
|
+
})
|
|
20
|
+
).to_return(
|
|
21
|
+
body: MultiJson.dump({
|
|
22
|
+
'cluster_name' => 'foobar',
|
|
23
|
+
'status' => 'green',
|
|
24
|
+
'timed_out' => false,
|
|
25
|
+
'number_of_nodes' => 2,
|
|
26
|
+
'number_of_data_nodes' => 2,
|
|
27
|
+
'active_primary_shards' => 5,
|
|
28
|
+
'active_shards' => 10,
|
|
29
|
+
'relocating_shards' => 0,
|
|
30
|
+
'initializing_shards' => 0,
|
|
31
|
+
'unassigned_shards' => 0
|
|
32
|
+
})
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
flush = stub_request(:post, 'localhost:9200/_all/_flush').to_return(
|
|
36
|
+
body: MultiJson.dump({
|
|
37
|
+
'ok' => true
|
|
38
|
+
})
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
disable_flush = stub_request(:put, 'localhost:9200/_all/_settings').with(
|
|
42
|
+
body: MultiJson.dump({
|
|
43
|
+
index: {
|
|
44
|
+
translog: {
|
|
45
|
+
disable_flush: true
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
).to_return(
|
|
50
|
+
body: MultiJson.dump({
|
|
51
|
+
'ok' => true
|
|
52
|
+
})
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
enable_flush = stub_request(:put, 'localhost:9200/_all/_settings').with(
|
|
56
|
+
body: MultiJson.dump({
|
|
57
|
+
index: {
|
|
58
|
+
translog: {
|
|
59
|
+
disable_flush: false
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
).to_return(
|
|
64
|
+
body: MultiJson.dump({
|
|
65
|
+
'ok' => true
|
|
66
|
+
})
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
start(:snapshot, args)
|
|
70
|
+
expect(health_check).to have_been_requested
|
|
71
|
+
expect(flush).to have_been_requested
|
|
72
|
+
expect(disable_flush).to have_been_requested
|
|
73
|
+
expect(enable_flush).to have_been_requested
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Elasticsnap::EbsSnapshot do
|
|
4
|
+
it 'requires security group' do
|
|
5
|
+
expect { described_class.new }.to raise_error ArgumentError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
let(:security_group) { double(:security_group, name: 'elasticsearch') }
|
|
9
|
+
let(:snapshotter) { described_class.new(security_group: security_group.name) }
|
|
10
|
+
let(:snapshots) { [double(:snapshot1, add_volume_tags: true), double(:snapshot2, add_volume_tags: true)] }
|
|
11
|
+
let(:volumes) { [double(:volume1, id: 'vol-123', snapshot: snapshots[0]), double(:volume2, id: 'vol-234', snapshot: snapshots[1])] }
|
|
12
|
+
|
|
13
|
+
describe '#snapshot' do
|
|
14
|
+
before do
|
|
15
|
+
allow(snapshotter).to receive(:wrap_snapshot) do |snapshot|
|
|
16
|
+
snapshot
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
allow(Elasticsnap::SecurityGroup).to receive(:new).with(name: security_group.name).and_return(security_group)
|
|
20
|
+
allow(security_group).to receive(:volumes).and_return(volumes)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'gets a list of volumes from the security group' do
|
|
24
|
+
snapshotter.snapshot
|
|
25
|
+
expect(Elasticsnap::SecurityGroup).to have_received(:new).with(name: security_group.name)
|
|
26
|
+
expect(security_group).to have_received(:volumes)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'snapshots each volume' do
|
|
30
|
+
snapshotter.snapshot
|
|
31
|
+
volumes.each do |volume|
|
|
32
|
+
expect(volume).to have_received(:snapshot)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'adds volume tags to each snapshot' do
|
|
37
|
+
snapshotter.snapshot
|
|
38
|
+
snapshots.each do |snapshot|
|
|
39
|
+
expect(snapshot).to have_received(:add_volume_tags)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe '#wrap_snapshot' do
|
|
45
|
+
let(:snapshot_body) { double(:snapshot_body) }
|
|
46
|
+
let(:snapshot_response) { double(:snapshot_response, body: snapshot_body) }
|
|
47
|
+
let(:snapshot) { double(:snapshot) }
|
|
48
|
+
|
|
49
|
+
before do
|
|
50
|
+
allow(Fog::Compute::AWS::Snapshot).to receive(:new).with(snapshot_body).and_return(snapshot)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'bundles the response in a snapshot model' do
|
|
54
|
+
snapshotter.wrap_snapshot(snapshot_response)
|
|
55
|
+
expect(Fog::Compute::AWS::Snapshot).to have_received(:new)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'extends the snapshot instance with SnapshotVolumeTags' do
|
|
59
|
+
expect(snapshot).to receive(:extend).with(Elasticsnap::SnapshotVolumeTags)
|
|
60
|
+
snapshotter.wrap_snapshot(snapshot_response)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Elasticsnap::FreezeElasticsearch do
|
|
4
|
+
it 'requires url' do
|
|
5
|
+
expect { described_class.new }.to raise_error ArgumentError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
let(:freeze) { described_class.new(url: 'localhost:9200')}
|
|
9
|
+
let(:disable_flush_hash) do
|
|
10
|
+
{
|
|
11
|
+
index: '_all',
|
|
12
|
+
data: {
|
|
13
|
+
index: {
|
|
14
|
+
translog: {
|
|
15
|
+
disable_flush: true
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
let(:enable_flush_hash) do
|
|
22
|
+
{
|
|
23
|
+
index: '_all',
|
|
24
|
+
data: {
|
|
25
|
+
index: {
|
|
26
|
+
translog: {
|
|
27
|
+
disable_flush: false
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
before do
|
|
35
|
+
allow(Flex).to receive(:flush_index).and_return({'ok' => true})
|
|
36
|
+
allow(Flex).to receive(:update_index_settings).with(disable_flush_hash).and_return({'ok' => true})
|
|
37
|
+
allow(Flex).to receive(:update_index_settings).with(enable_flush_hash).and_return({'ok' => true})
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'flushes elasticsearch' do
|
|
41
|
+
freeze.freeze
|
|
42
|
+
expect(Flex).to have_received(:flush_index).with(index: '_all')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'when flushing fails' do
|
|
46
|
+
before do
|
|
47
|
+
allow(Flex).to receive(:flush_index).and_return({'ok' => false})
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'raises FlushFailed' do
|
|
51
|
+
expect { freeze.freeze }.to raise_error Elasticsnap::FreezeElasticsearch::FlushFailed
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'disables flushing' do
|
|
56
|
+
freeze.freeze
|
|
57
|
+
expect(Flex).to have_received(:update_index_settings).with(disable_flush_hash)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context 'when disable flushing fails' do
|
|
61
|
+
before do
|
|
62
|
+
allow(Flex).to receive(:update_index_settings).with(disable_flush_hash).and_return({'ok' => false})
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'raises DisableFlushFailed' do
|
|
66
|
+
expect { freeze.freeze }.to raise_error Elasticsnap::FreezeElasticsearch::DisableFlushFailed
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it 'calls the passed block' do
|
|
71
|
+
block_called = false
|
|
72
|
+
freeze.freeze do
|
|
73
|
+
block_called = true
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
expect(block_called).to be_true
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'enables flushing' do
|
|
80
|
+
freeze.freeze
|
|
81
|
+
expect(Flex).to have_received(:update_index_settings).with(enable_flush_hash)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
context 'when enable flushing fails' do
|
|
85
|
+
before do
|
|
86
|
+
allow(Flex).to receive(:update_index_settings).with(enable_flush_hash).and_return({'ok' => false})
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'raises EnableFlushFailed' do
|
|
90
|
+
expect { freeze.freeze }.to raise_error Elasticsnap::FreezeElasticsearch::EnableFlushFailed
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
context 'when an exception is raised from the block' do
|
|
95
|
+
it 'enables flushing' do
|
|
96
|
+
expect { freeze.freeze do
|
|
97
|
+
raise 'BOOM'
|
|
98
|
+
end }.to raise_error 'BOOM'
|
|
99
|
+
expect(Flex).to have_received(:update_index_settings).with(enable_flush_hash)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|