synapse-aurora 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +23 -0
- data/.mailmap +3 -0
- data/.nix/Gemfile.nix +141 -0
- data/.nix/rubylibs.nix +42 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/Makefile +6 -0
- data/README.md +339 -0
- data/Rakefile +8 -0
- data/bin/synapse +62 -0
- data/config/hostheader_test.json +71 -0
- data/config/svcdir_test.json +46 -0
- data/config/synapse.conf.json +90 -0
- data/config/synapse_services/service1.json +24 -0
- data/config/synapse_services/service2.json +24 -0
- data/default.nix +66 -0
- data/lib/synapse.rb +85 -0
- data/lib/synapse/base.rb +5 -0
- data/lib/synapse/haproxy.rb +797 -0
- data/lib/synapse/log.rb +24 -0
- data/lib/synapse/service_watcher.rb +36 -0
- data/lib/synapse/service_watcher/base.rb +109 -0
- data/lib/synapse/service_watcher/dns.rb +109 -0
- data/lib/synapse/service_watcher/docker.rb +120 -0
- data/lib/synapse/service_watcher/ec2tag.rb +133 -0
- data/lib/synapse/service_watcher/zookeeper.rb +153 -0
- data/lib/synapse/service_watcher/zookeeper_aurora.rb +76 -0
- data/lib/synapse/service_watcher/zookeeper_dns.rb +232 -0
- data/lib/synapse/version.rb +3 -0
- data/spec/lib/synapse/haproxy_spec.rb +32 -0
- data/spec/lib/synapse/service_watcher_base_spec.rb +55 -0
- data/spec/lib/synapse/service_watcher_docker_spec.rb +152 -0
- data/spec/lib/synapse/service_watcher_ec2tags_spec.rb +220 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/configuration.rb +9 -0
- data/spec/support/minimum.conf.yaml +27 -0
- data/synapse.gemspec +33 -0
- metadata +227 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class MockWatcher; end;
|
4
|
+
|
5
|
+
describe Synapse::Haproxy do
|
6
|
+
subject { Synapse::Haproxy.new(config['haproxy']) }
|
7
|
+
|
8
|
+
let(:mockwatcher) do
|
9
|
+
mockWatcher = double(Synapse::ServiceWatcher)
|
10
|
+
allow(mockWatcher).to receive(:name).and_return('example_service')
|
11
|
+
backends = [{ 'host' => 'somehost', 'port' => '5555'}]
|
12
|
+
allow(mockWatcher).to receive(:backends).and_return(backends)
|
13
|
+
allow(mockWatcher).to receive(:haproxy).and_return({'server_options' => "check inter 2000 rise 3 fall 2"})
|
14
|
+
mockWatcher
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'updating the config' do
|
18
|
+
expect(subject).to receive(:generate_config)
|
19
|
+
subject.update_config([mockwatcher])
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'generates backend stanza' do
|
23
|
+
mockConfig = []
|
24
|
+
expect(subject.generate_backend_stanza(mockwatcher, mockConfig)).to eql(["\nbackend example_service", [], ["\tserver somehost:5555 somehost:5555 cookie somehost:5555 check inter 2000 rise 3 fall 2"]])
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'generates backend stanza without cookies for tcp mode' do
|
28
|
+
mockConfig = ['mode tcp']
|
29
|
+
expect(subject.generate_backend_stanza(mockwatcher, mockConfig)).to eql(["\nbackend example_service", ["\tmode tcp"], ["\tserver somehost:5555 somehost:5555 check inter 2000 rise 3 fall 2"]])
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class Synapse::BaseWatcher
|
4
|
+
attr_reader :should_exit, :default_servers
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Synapse::BaseWatcher do
|
8
|
+
let(:mocksynapse) { double() }
|
9
|
+
subject { Synapse::BaseWatcher.new(args, mocksynapse) }
|
10
|
+
let(:testargs) { { 'name' => 'foo', 'discovery' => { 'method' => 'base' }, 'haproxy' => {} }}
|
11
|
+
|
12
|
+
def remove_arg(name)
|
13
|
+
args = testargs.clone
|
14
|
+
args.delete name
|
15
|
+
args
|
16
|
+
end
|
17
|
+
|
18
|
+
context "can construct normally" do
|
19
|
+
let(:args) { testargs }
|
20
|
+
it('can at least construct') { expect { subject }.not_to raise_error }
|
21
|
+
end
|
22
|
+
|
23
|
+
['name', 'discovery', 'haproxy'].each do |to_remove|
|
24
|
+
context "without #{to_remove} argument" do
|
25
|
+
let(:args) { remove_arg to_remove }
|
26
|
+
it('gots bang') { expect { subject }.to raise_error(ArgumentError, "missing required option #{to_remove}") }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "normal tests" do
|
31
|
+
let(:args) { testargs }
|
32
|
+
it('is running') { expect(subject.should_exit).to equal(false) }
|
33
|
+
it('can ping') { expect(subject.ping?).to equal(true) }
|
34
|
+
it('can be stopped') do
|
35
|
+
subject.stop
|
36
|
+
expect(subject.should_exit).to equal(true)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "with default_servers" do
|
41
|
+
default_servers = ['server1', 'server2']
|
42
|
+
let(:args) { testargs.merge({'default_servers' => default_servers}) }
|
43
|
+
it('sets default backends to default_servers') { expect(subject.backends).to equal(default_servers) }
|
44
|
+
|
45
|
+
context "with keep_default_servers set" do
|
46
|
+
let(:args) { testargs.merge({'default_servers' => default_servers, 'keep_default_servers' => true}) }
|
47
|
+
let(:new_backends) { ['discovered1', 'discovered2'] }
|
48
|
+
|
49
|
+
it('keeps default_servers when setting backends') do
|
50
|
+
subject.send(:set_backends, new_backends)
|
51
|
+
expect(subject.backends).to eq(default_servers + new_backends)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class Synapse::DockerWatcher
|
4
|
+
attr_reader :check_interval, :watcher, :synapse
|
5
|
+
attr_accessor :default_servers
|
6
|
+
end
|
7
|
+
|
8
|
+
describe Synapse::DockerWatcher do
|
9
|
+
let(:mocksynapse) { double() }
|
10
|
+
subject { Synapse::DockerWatcher.new(testargs, mocksynapse) }
|
11
|
+
let(:testargs) { { 'name' => 'foo', 'discovery' => { 'method' => 'docker', 'servers' => [{'host' => 'server1.local', 'name' => 'mainserver'}], 'image_name' => 'mycool/image', 'container_port' => 6379 }, 'haproxy' => {} }}
|
12
|
+
before(:each) do
|
13
|
+
allow(subject.log).to receive(:warn)
|
14
|
+
allow(subject.log).to receive(:info)
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_arg(name, value)
|
18
|
+
args = testargs.clone
|
19
|
+
args['discovery'][name] = value
|
20
|
+
args
|
21
|
+
end
|
22
|
+
|
23
|
+
context "can construct normally" do
|
24
|
+
it('can at least construct') { expect { subject }.not_to raise_error }
|
25
|
+
end
|
26
|
+
|
27
|
+
context "normal tests" do
|
28
|
+
it('starts a watcher thread') do
|
29
|
+
watcher_mock = double()
|
30
|
+
expect(Thread).to receive(:new).and_return(watcher_mock)
|
31
|
+
subject.start
|
32
|
+
expect(subject.watcher).to equal(watcher_mock)
|
33
|
+
end
|
34
|
+
it('sets default check interval') do
|
35
|
+
expect(Thread).to receive(:new).and_return(double)
|
36
|
+
subject.start
|
37
|
+
expect(subject.check_interval).to eq(15.0)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "watch tests" do
|
42
|
+
before(:each) do
|
43
|
+
expect(subject).to receive(:sleep_until_next_check) do |arg|
|
44
|
+
subject.instance_variable_set('@should_exit', true)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
it('has a happy first run path, configuring backends') do
|
48
|
+
expect(subject).to receive(:containers).and_return(['container1'])
|
49
|
+
expect(subject).to receive(:configure_backends).with(['container1'])
|
50
|
+
subject.send(:watch)
|
51
|
+
end
|
52
|
+
it('does not call configure_backends if there is no change') do
|
53
|
+
expect(subject).to receive(:containers).and_return([])
|
54
|
+
expect(subject).to_not receive(:configure_backends)
|
55
|
+
subject.send(:watch)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
context "watch eats exceptions" do
|
59
|
+
it "blows up when finding containers" do
|
60
|
+
expect(subject).to receive(:containers) do |arg|
|
61
|
+
subject.instance_variable_set('@should_exit', true)
|
62
|
+
raise('throw exception inside watch')
|
63
|
+
end
|
64
|
+
expect { subject.send(:watch) }.not_to raise_error
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "configure_backends tests" do
|
69
|
+
before(:each) do
|
70
|
+
expect(subject.synapse).to receive(:'reconfigure!').at_least(:once)
|
71
|
+
end
|
72
|
+
it 'runs' do
|
73
|
+
expect { subject.send(:configure_backends, []) }.not_to raise_error
|
74
|
+
end
|
75
|
+
it 'sets backends right' do
|
76
|
+
subject.send(:configure_backends, ['foo'])
|
77
|
+
expect(subject.backends).to eq(['foo'])
|
78
|
+
end
|
79
|
+
it 'resets to default backends if no container found' do
|
80
|
+
subject.default_servers = ['fallback1']
|
81
|
+
subject.send(:configure_backends, ['foo'])
|
82
|
+
expect(subject.backends).to eq(['foo'])
|
83
|
+
subject.send(:configure_backends, [])
|
84
|
+
expect(subject.backends).to eq(['fallback1'])
|
85
|
+
end
|
86
|
+
it 'does not reset to default backends if there are no default backends' do
|
87
|
+
subject.default_servers = []
|
88
|
+
subject.send(:configure_backends, ['foo'])
|
89
|
+
expect(subject.backends).to eq(['foo'])
|
90
|
+
subject.send(:configure_backends, [])
|
91
|
+
expect(subject.backends).to eq(['foo'])
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "rewrite_container_ports tests" do
|
96
|
+
it 'doesnt break if Ports => nil' do
|
97
|
+
subject.send(:rewrite_container_ports, nil)
|
98
|
+
end
|
99
|
+
it 'works for old style port mappings' do
|
100
|
+
expect(subject.send(:rewrite_container_ports, "0.0.0.0:49153->6379/tcp, 0.0.0.0:49154->6390/tcp")).to \
|
101
|
+
eql({'6379' => '49153', '6390' => '49154'})
|
102
|
+
end
|
103
|
+
it 'works for new style port mappings' do
|
104
|
+
expect(subject.send(:rewrite_container_ports, [{'PrivatePort' => 6379, 'PublicPort' => 49153}, {'PublicPort' => 49154, 'PrivatePort' => 6390}])).to \
|
105
|
+
eql({'6379' => '49153', '6390' => '49154'})
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "container discovery tests" do
|
110
|
+
before(:each) do
|
111
|
+
getter = double()
|
112
|
+
expect(getter).to receive(:get)
|
113
|
+
expect(Docker).to receive(:connection).and_return(getter)
|
114
|
+
end
|
115
|
+
|
116
|
+
it('has a sane uri') { subject.send(:containers); expect(Docker.url).to eql('http://server1.local:4243') }
|
117
|
+
|
118
|
+
context 'old style port mappings' do
|
119
|
+
context 'works for one container' do
|
120
|
+
let(:docker_data) { [{"Ports" => "0.0.0.0:49153->6379/tcp, 0.0.0.0:49154->6390/tcp", "Image" => "mycool/image:tagname"}] }
|
121
|
+
it do
|
122
|
+
expect(Docker::Util).to receive(:parse_json).and_return(docker_data)
|
123
|
+
expect(subject.send(:containers)).to eql([{"name"=>"mainserver", "host"=>"server1.local", "port"=>"49153"}])
|
124
|
+
end
|
125
|
+
end
|
126
|
+
context 'works for multiple containers' do
|
127
|
+
let(:docker_data) { [{"Ports" => "0.0.0.0:49153->6379/tcp, 0.0.0.0:49154->6390/tcp", "Image" => "mycool/image:tagname"}, {"Ports" => "0.0.0.0:49155->6379/tcp", "Image" => "mycool/image:tagname"}] }
|
128
|
+
it do
|
129
|
+
expect(Docker::Util).to receive(:parse_json).and_return(docker_data)
|
130
|
+
expect(subject.send(:containers)).to eql([{"name"=>"mainserver", "host"=>"server1.local", "port"=>"49153"},{"name"=>"mainserver", "host"=>"server1.local", "port"=>"49155"}])
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'new style port mappings' do
|
136
|
+
let(:docker_data) { [{"Ports" => [{'PrivatePort' => 6379, 'PublicPort' => 49153}, {'PublicPort' => 49154, 'PrivatePort' => 6390}], "Image" => "mycool/image:tagname"}] }
|
137
|
+
it do
|
138
|
+
expect(Docker::Util).to receive(:parse_json).and_return(docker_data)
|
139
|
+
expect(subject.send(:containers)).to eql([{"name"=>"mainserver", "host"=>"server1.local", "port"=>"49153"}])
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'filters out wrong images' do
|
144
|
+
let(:docker_data) { [{"Ports" => "0.0.0.0:49153->6379/tcp, 0.0.0.0:49154->6390/tcp", "Image" => "mycool/image:tagname"}, {"Ports" => "0.0.0.0:49155->6379/tcp", "Image" => "wrong/image:tagname"}] }
|
145
|
+
it do
|
146
|
+
expect(Docker::Util).to receive(:parse_json).and_return(docker_data)
|
147
|
+
expect(subject.send(:containers)).to eql([{"name"=>"mainserver", "host"=>"server1.local", "port"=>"49153"}])
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
@@ -0,0 +1,220 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'logging'
|
3
|
+
|
4
|
+
class Synapse::EC2Watcher
|
5
|
+
attr_reader :synapse
|
6
|
+
attr_accessor :default_servers, :ec2
|
7
|
+
end
|
8
|
+
|
9
|
+
class FakeAWSInstance
|
10
|
+
def ip_address
|
11
|
+
@ip_address ||= fake_address
|
12
|
+
end
|
13
|
+
|
14
|
+
def private_ip_address
|
15
|
+
@private_ip_address ||= fake_address
|
16
|
+
end
|
17
|
+
|
18
|
+
def dns_name
|
19
|
+
@dns_name ||= "ec2-#{ip_address.gsub('.', '-')}.eu-test-1.compute.amazonaws.com"
|
20
|
+
end
|
21
|
+
|
22
|
+
def private_dns_name
|
23
|
+
@private_dns_name ||= "ip-#{private_ip_address.gsub('.', '-')}.eu-test-1.compute.internal"
|
24
|
+
end
|
25
|
+
|
26
|
+
def fake_address
|
27
|
+
4.times.map { (0...254).to_a.shuffle.pop.to_s }.join('.')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe Synapse::EC2Watcher do
|
32
|
+
let(:mock_synapse) { double }
|
33
|
+
subject { Synapse::EC2Watcher.new(basic_config, mock_synapse) }
|
34
|
+
|
35
|
+
let(:basic_config) do
|
36
|
+
{ 'name' => 'ec2tagtest',
|
37
|
+
'haproxy' => {
|
38
|
+
'port' => '8080',
|
39
|
+
'server_port_override' => '8081'
|
40
|
+
},
|
41
|
+
"discovery" => {
|
42
|
+
"method" => "ec2tag",
|
43
|
+
"tag_name" => "fuNNy_tag_name",
|
44
|
+
"tag_value" => "funkyTagValue",
|
45
|
+
"aws_region" => 'eu-test-1',
|
46
|
+
"aws_access_key_id" => 'ABCDEFGHIJKLMNOPQRSTU',
|
47
|
+
"aws_secret_access_key" => 'verylongfakekeythatireallyneedtogenerate'
|
48
|
+
}
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
before(:all) do
|
53
|
+
# Clean up ENV so we don't inherit any actual AWS config.
|
54
|
+
%w[AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_REGION].each { |k| ENV.delete(k) }
|
55
|
+
end
|
56
|
+
|
57
|
+
before(:each) do
|
58
|
+
# https://ruby.awsblog.com/post/Tx2SU6TYJWQQLC3/Stubbing-AWS-Responses
|
59
|
+
# always returns empty results, so data may have to be faked.
|
60
|
+
AWS.stub!
|
61
|
+
end
|
62
|
+
|
63
|
+
def remove_discovery_arg(name)
|
64
|
+
args = basic_config.clone
|
65
|
+
args['discovery'].delete name
|
66
|
+
args
|
67
|
+
end
|
68
|
+
|
69
|
+
def remove_haproxy_arg(name)
|
70
|
+
args = basic_config.clone
|
71
|
+
args['haproxy'].delete name
|
72
|
+
args
|
73
|
+
end
|
74
|
+
|
75
|
+
def munge_haproxy_arg(name, new_value)
|
76
|
+
args = basic_config.clone
|
77
|
+
args['haproxy'][name] = new_value
|
78
|
+
args
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '#new' do
|
82
|
+
let(:args) { basic_config }
|
83
|
+
|
84
|
+
it 'instantiates cleanly with basic config' do
|
85
|
+
expect { subject }.not_to raise_error
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when missing arguments' do
|
89
|
+
it 'complains if aws_region is missing' do
|
90
|
+
expect {
|
91
|
+
Synapse::EC2Watcher.new(remove_discovery_arg('aws_region'), mock_synapse)
|
92
|
+
}.to raise_error(ArgumentError, /Missing aws_region/)
|
93
|
+
end
|
94
|
+
it 'complains if aws_access_key_id is missing' do
|
95
|
+
expect {
|
96
|
+
Synapse::EC2Watcher.new(remove_discovery_arg('aws_access_key_id'), mock_synapse)
|
97
|
+
}.to raise_error(ArgumentError, /Missing aws_access_key_id/)
|
98
|
+
end
|
99
|
+
it 'complains if aws_secret_access_key is missing' do
|
100
|
+
expect {
|
101
|
+
Synapse::EC2Watcher.new(remove_discovery_arg('aws_secret_access_key'), mock_synapse)
|
102
|
+
}.to raise_error(ArgumentError, /Missing aws_secret_access_key/)
|
103
|
+
end
|
104
|
+
it 'complains if server_port_override is missing' do
|
105
|
+
expect {
|
106
|
+
Synapse::EC2Watcher.new(remove_haproxy_arg('server_port_override'), mock_synapse)
|
107
|
+
}.to raise_error(ArgumentError, /Missing server_port_override/)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'invalid data' do
|
112
|
+
it 'complains if the haproxy server_port_override is not a number' do
|
113
|
+
expect {
|
114
|
+
Synapse::EC2Watcher.new(munge_haproxy_arg('server_port_override', '80deadbeef'), mock_synapse)
|
115
|
+
}.to raise_error(ArgumentError, /Invalid server_port_override/)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "instance discovery" do
|
121
|
+
let(:instance1) { FakeAWSInstance.new }
|
122
|
+
let(:instance2) { FakeAWSInstance.new }
|
123
|
+
|
124
|
+
context 'using the AWS API' do
|
125
|
+
let(:ec2_client) { double('AWS::EC2') }
|
126
|
+
let(:instance_collection) { double('AWS::EC2::InstanceCollection') }
|
127
|
+
|
128
|
+
before do
|
129
|
+
subject.ec2 = ec2_client
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'fetches instances and filter instances' do
|
133
|
+
# Unfortunately there's quite a bit going on here, but this is
|
134
|
+
# a chained call to get then filter EC2 instances, which is
|
135
|
+
# done remotely; breaking into separate calls would result in
|
136
|
+
# unnecessary data being retrieved.
|
137
|
+
|
138
|
+
subject.ec2.should_receive(:instances).and_return(instance_collection)
|
139
|
+
|
140
|
+
instance_collection.should_receive(:tagged).with('foo').and_return(instance_collection)
|
141
|
+
instance_collection.should_receive(:tagged_values).with('bar').and_return(instance_collection)
|
142
|
+
instance_collection.should_receive(:select).and_return(instance_collection)
|
143
|
+
|
144
|
+
subject.send(:instances_with_tags, 'foo', 'bar')
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'returned backend data structure' do
|
149
|
+
before do
|
150
|
+
subject.stub(:instances_with_tags).and_return([instance1, instance2])
|
151
|
+
end
|
152
|
+
|
153
|
+
let(:backends) { subject.send(:discover_instances) }
|
154
|
+
|
155
|
+
it 'returns an Array of backend name/host/port Hashes' do
|
156
|
+
|
157
|
+
expect { backends.all? {|b| %w[name host port].each {|k| b.has_key?(k) }} }.to be_true
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'sets the backend port to server_port_override for all backends' do
|
161
|
+
backends = subject.send(:discover_instances)
|
162
|
+
expect {
|
163
|
+
backends.all? { |b| b['port'] == basic_config['haproxy']['server_port_override'] }
|
164
|
+
}.to be_true
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context 'returned instance fields' do
|
169
|
+
before do
|
170
|
+
subject.stub(:instances_with_tags).and_return([instance1])
|
171
|
+
end
|
172
|
+
|
173
|
+
let(:backend) { subject.send(:discover_instances).pop }
|
174
|
+
|
175
|
+
it "returns an instance's private IP as the hostname" do
|
176
|
+
expect( backend['host'] ).to eq instance1.private_ip_address
|
177
|
+
end
|
178
|
+
|
179
|
+
it "returns an instance's private hostname as the server name" do
|
180
|
+
expect( backend['name'] ).to eq instance1.private_dns_name
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context "configure_backends tests" do
|
186
|
+
let(:backend1) { { 'name' => 'foo', 'host' => 'foo.backend.tld', 'port' => '123' } }
|
187
|
+
let(:backend2) { { 'name' => 'bar', 'host' => 'bar.backend.tld', 'port' => '456' } }
|
188
|
+
let(:fallback) { { 'name' => 'fall', 'host' => 'fall.backend.tld', 'port' => '789' } }
|
189
|
+
|
190
|
+
before(:each) do
|
191
|
+
expect(subject.synapse).to receive(:'reconfigure!').at_least(:once)
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'runs' do
|
195
|
+
expect { subject.send(:configure_backends, []) }.not_to raise_error
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'sets backends correctly' do
|
199
|
+
subject.send(:configure_backends, [ backend1, backend2 ])
|
200
|
+
expect(subject.backends).to eq([ backend1, backend2 ])
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'resets to default backends if no instances are found' do
|
204
|
+
subject.default_servers = [ fallback ]
|
205
|
+
subject.send(:configure_backends, [ backend1 ])
|
206
|
+
expect(subject.backends).to eq([ backend1 ])
|
207
|
+
subject.send(:configure_backends, [])
|
208
|
+
expect(subject.backends).to eq([ fallback ])
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'does not reset to default backends if there are no default backends' do
|
212
|
+
subject.default_servers = []
|
213
|
+
subject.send(:configure_backends, [ backend1 ])
|
214
|
+
expect(subject.backends).to eq([ backend1 ])
|
215
|
+
subject.send(:configure_backends, [])
|
216
|
+
expect(subject.backends).to eq([ backend1 ])
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|