dalli-elasticache 0.2.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +31 -16
- data/Rakefile +7 -5
- data/lib/dalli/elasticache/auto_discovery/base_command.rb +42 -0
- data/lib/dalli/elasticache/auto_discovery/config_command.rb +45 -0
- data/lib/dalli/elasticache/auto_discovery/config_response.rb +15 -18
- data/lib/dalli/elasticache/auto_discovery/endpoint.rb +28 -59
- data/lib/dalli/elasticache/auto_discovery/node.rb +39 -0
- data/lib/dalli/elasticache/auto_discovery/stats_command.rb +23 -0
- data/lib/dalli/elasticache/auto_discovery/stats_response.rb +15 -12
- data/lib/dalli/elasticache/version.rb +3 -1
- data/lib/dalli/elasticache.rb +40 -14
- data/lib/dalli-elasticache.rb +3 -1
- data/spec/config_command_spec.rb +101 -0
- data/spec/config_response_spec.rb +15 -11
- data/spec/elasticache_spec.rb +93 -27
- data/spec/endpoint_spec.rb +77 -6
- data/spec/node_spec.rb +82 -0
- data/spec/spec_helper.rb +7 -10
- data/spec/stats_command_spec.rb +90 -0
- data/spec/stats_response_spec.rb +111 -8
- metadata +94 -12
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'spec_helper'
|
4
|
+
|
5
|
+
describe 'Dalli::Elasticache::AutoDiscovery::ConfigCommand' do
|
6
|
+
let(:host) { Faker::Internet.domain_name(subdomain: true) }
|
7
|
+
let(:port) { rand(1024..16_023) }
|
8
|
+
let(:command) { Dalli::Elasticache::AutoDiscovery::ConfigCommand.new(host, port, engine_version) }
|
9
|
+
|
10
|
+
let(:socket_response_lines) do
|
11
|
+
[
|
12
|
+
"CONFIG cluster 0 142\r\n",
|
13
|
+
"12\r\n",
|
14
|
+
'mycluster.0001.cache.amazonaws.com|10.112.21.1|11211 '\
|
15
|
+
'mycluster.0002.cache.amazonaws.com|10.112.21.2|11211 '\
|
16
|
+
"mycluster.0003.cache.amazonaws.com|10.112.21.3|11211\r\n",
|
17
|
+
"\r\n",
|
18
|
+
"END\r\n"
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:expected_nodes) do
|
23
|
+
[
|
24
|
+
Dalli::Elasticache::AutoDiscovery::Node.new('mycluster.0001.cache.amazonaws.com',
|
25
|
+
'10.112.21.1',
|
26
|
+
11_211),
|
27
|
+
Dalli::Elasticache::AutoDiscovery::Node.new('mycluster.0002.cache.amazonaws.com',
|
28
|
+
'10.112.21.2',
|
29
|
+
11_211),
|
30
|
+
Dalli::Elasticache::AutoDiscovery::Node.new('mycluster.0003.cache.amazonaws.com',
|
31
|
+
'10.112.21.3',
|
32
|
+
11_211)
|
33
|
+
]
|
34
|
+
end
|
35
|
+
|
36
|
+
let(:mock_socket) { instance_double(TCPSocket) }
|
37
|
+
|
38
|
+
before do
|
39
|
+
allow(TCPSocket).to receive(:new).with(host, port).and_return(mock_socket)
|
40
|
+
allow(mock_socket).to receive(:close)
|
41
|
+
allow(mock_socket).to receive(:puts).with(cmd)
|
42
|
+
allow(mock_socket).to receive(:readline).and_return(*socket_response_lines)
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when the engine_version is 1.4.5' do
|
46
|
+
let(:engine_version) { '1.4.5' } # This is the only pre-1.4.14 version available on AWS
|
47
|
+
let(:cmd) { Dalli::Elasticache::AutoDiscovery::ConfigCommand::LEGACY_CONFIG_COMMAND }
|
48
|
+
|
49
|
+
context 'when the socket returns a valid response' do
|
50
|
+
before do
|
51
|
+
allow(mock_socket).to receive(:readline).and_return(*socket_response_lines)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'sends the legacy command and returns a ConfigResponse with expected values' do
|
55
|
+
response = command.response
|
56
|
+
expect(response).to be_a Dalli::Elasticache::AutoDiscovery::ConfigResponse
|
57
|
+
expect(response.version).to eq(12)
|
58
|
+
expect(response.nodes).to eq(expected_nodes)
|
59
|
+
expect(mock_socket).to have_received(:close)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when the engine_version is greater than or equal to 1.4.14' do
|
65
|
+
let(:engine_version) { ['1.4.14', '1.5.6', '1.6.10'].sample }
|
66
|
+
let(:cmd) { Dalli::Elasticache::AutoDiscovery::ConfigCommand::CONFIG_COMMAND }
|
67
|
+
|
68
|
+
context 'when the socket returns a valid response' do
|
69
|
+
before do
|
70
|
+
allow(mock_socket).to receive(:readline).and_return(*socket_response_lines)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'sends the current command and returns a ConfigResponse with expected values' do
|
74
|
+
response = command.response
|
75
|
+
expect(response).to be_a Dalli::Elasticache::AutoDiscovery::ConfigResponse
|
76
|
+
expect(response.version).to eq(12)
|
77
|
+
expect(response.nodes).to eq(expected_nodes)
|
78
|
+
expect(mock_socket).to have_received(:close)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when the engine_version is UNKNOWN or some other string' do
|
84
|
+
let(:engine_version) { ['UNKNOWN', SecureRandom.hex(4), nil].sample }
|
85
|
+
let(:cmd) { Dalli::Elasticache::AutoDiscovery::ConfigCommand::CONFIG_COMMAND }
|
86
|
+
|
87
|
+
context 'when the socket returns a valid response' do
|
88
|
+
before do
|
89
|
+
allow(mock_socket).to receive(:readline).and_return(*socket_response_lines)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'sends the current command and returns a ConfigResponse with expected values' do
|
93
|
+
response = command.response
|
94
|
+
expect(response).to be_a Dalli::Elasticache::AutoDiscovery::ConfigResponse
|
95
|
+
expect(response.version).to eq(12)
|
96
|
+
expect(response.nodes).to eq(expected_nodes)
|
97
|
+
expect(mock_socket).to have_received(:close)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -1,32 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'spec_helper'
|
2
4
|
|
3
5
|
describe 'Dalli::Elasticache::AutoDiscovery::ConfigResponse' do
|
4
6
|
let :response do
|
5
|
-
text = "CONFIG cluster 0 141\r\n12\nmycluster.0001.cache.amazonaws.com|10.112.21.1|11211
|
7
|
+
text = "CONFIG cluster 0 141\r\n12\nmycluster.0001.cache.amazonaws.com|10.112.21.1|11211 "\
|
8
|
+
'mycluster.0002.cache.amazonaws.com|10.112.21.2|11211 '\
|
9
|
+
"mycluster.0003.cache.amazonaws.com|10.112.21.3|11211\n\r\n"
|
6
10
|
Dalli::Elasticache::AutoDiscovery::ConfigResponse.new(text)
|
7
11
|
end
|
8
|
-
|
12
|
+
|
9
13
|
describe '#version' do
|
10
14
|
it 'parses version' do
|
11
|
-
response.version.
|
15
|
+
expect(response.version).to eq 12
|
12
16
|
end
|
13
17
|
end
|
14
18
|
|
15
19
|
describe '#nodes' do
|
16
20
|
it 'parses hosts' do
|
17
|
-
response.nodes.map
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
expect(response.nodes.map(&:host)).to eq [
|
22
|
+
'mycluster.0001.cache.amazonaws.com',
|
23
|
+
'mycluster.0002.cache.amazonaws.com',
|
24
|
+
'mycluster.0003.cache.amazonaws.com'
|
21
25
|
]
|
22
26
|
end
|
23
|
-
|
27
|
+
|
24
28
|
it 'parses ip addresses' do
|
25
|
-
response.nodes.map
|
29
|
+
expect(response.nodes.map(&:ip)).to eq ['10.112.21.1', '10.112.21.2', '10.112.21.3']
|
26
30
|
end
|
27
|
-
|
31
|
+
|
28
32
|
it 'parses ports' do
|
29
|
-
response.nodes.map
|
33
|
+
expect(response.nodes.map(&:port)).to eq [11_211, 11_211, 11_211]
|
30
34
|
end
|
31
35
|
end
|
32
36
|
end
|
data/spec/elasticache_spec.rb
CHANGED
@@ -1,62 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'spec_helper'
|
2
4
|
|
3
5
|
describe 'Dalli::ElastiCache::Endpoint' do
|
4
|
-
let(:
|
5
|
-
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
6
|
+
let(:dalli_options) do
|
7
|
+
{
|
8
|
+
expires_in: 24 * 60 * 60,
|
9
|
+
namespace: 'my_app',
|
10
|
+
compress: true
|
9
11
|
}
|
10
|
-
Dalli::ElastiCache.new("my-cluster.cfg.use1.cache.amazonaws.com:11211", options)
|
11
12
|
end
|
12
13
|
|
13
|
-
let(:
|
14
|
+
let(:host) { 'my-cluster.cfg.use1.cache.amazonaws.com' }
|
15
|
+
let(:port) { 11_211 }
|
16
|
+
let(:config_endpoint) { "#{host}:#{port}" }
|
17
|
+
let(:cache) do
|
18
|
+
Dalli::ElastiCache.new(config_endpoint, dalli_options)
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:config_text) do
|
22
|
+
"CONFIG cluster 0 141\r\n12\nmycluster.0001.cache.amazonaws.com|10.112.21.1|11211 "\
|
23
|
+
'mycluster.0002.cache.amazonaws.com|10.112.21.2|11211 '\
|
24
|
+
"mycluster.0003.cache.amazonaws.com|10.112.21.3|11211\n\r\n"
|
25
|
+
end
|
14
26
|
let(:response) { Dalli::Elasticache::AutoDiscovery::ConfigResponse.new(config_text) }
|
15
27
|
|
16
28
|
describe '.new' do
|
17
29
|
it 'builds endpoint' do
|
18
|
-
cache.endpoint.host.
|
19
|
-
cache.endpoint.port.
|
30
|
+
expect(cache.endpoint.host).to eq 'my-cluster.cfg.use1.cache.amazonaws.com'
|
31
|
+
expect(cache.endpoint.port).to eq 11_211
|
20
32
|
end
|
21
|
-
|
33
|
+
|
22
34
|
it 'stores Dalli options' do
|
23
|
-
cache.options[:expires_in].
|
24
|
-
cache.options[:namespace].
|
25
|
-
cache.options[:compress].
|
35
|
+
expect(cache.options[:expires_in]).to eq 24 * 60 * 60
|
36
|
+
expect(cache.options[:namespace]).to eq 'my_app'
|
37
|
+
expect(cache.options[:compress]).to eq true
|
26
38
|
end
|
27
39
|
end
|
28
|
-
|
40
|
+
|
29
41
|
describe '#client' do
|
30
|
-
|
31
|
-
|
42
|
+
let(:client) { cache.client }
|
43
|
+
let(:stub_endpoint) { Dalli::Elasticache::AutoDiscovery::Endpoint.new(config_endpoint) }
|
44
|
+
let(:mock_dalli) { instance_double(Dalli::Client) }
|
45
|
+
|
46
|
+
before do
|
47
|
+
allow(Dalli::Elasticache::AutoDiscovery::Endpoint).to receive(:new)
|
48
|
+
.with(config_endpoint).and_return(stub_endpoint)
|
49
|
+
allow(stub_endpoint).to receive(:config).and_return(response)
|
50
|
+
allow(Dalli::Client).to receive(:new)
|
51
|
+
.with(['mycluster.0001.cache.amazonaws.com:11211',
|
52
|
+
'mycluster.0002.cache.amazonaws.com:11211',
|
53
|
+
'mycluster.0003.cache.amazonaws.com:11211'],
|
54
|
+
dalli_options).and_return(mock_dalli)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'builds with node list and dalli options' do
|
58
|
+
expect(client).to eq(mock_dalli)
|
59
|
+
expect(stub_endpoint).to have_received(:config)
|
60
|
+
expect(Dalli::Client).to have_received(:new)
|
61
|
+
.with(['mycluster.0001.cache.amazonaws.com:11211',
|
62
|
+
'mycluster.0002.cache.amazonaws.com:11211',
|
63
|
+
'mycluster.0003.cache.amazonaws.com:11211'],
|
64
|
+
dalli_options)
|
65
|
+
end
|
32
66
|
end
|
33
|
-
|
67
|
+
|
34
68
|
describe '#servers' do
|
35
|
-
|
69
|
+
let(:stub_endpoint) { Dalli::Elasticache::AutoDiscovery::Endpoint.new(config_endpoint) }
|
70
|
+
|
71
|
+
before do
|
72
|
+
allow(Dalli::Elasticache::AutoDiscovery::Endpoint).to receive(:new)
|
73
|
+
.with(config_endpoint).and_return(stub_endpoint)
|
74
|
+
allow(stub_endpoint).to receive(:config).and_return(response)
|
75
|
+
end
|
36
76
|
|
37
77
|
it 'lists addresses and ports' do
|
38
|
-
cache.servers.
|
78
|
+
expect(cache.servers).to eq ['mycluster.0001.cache.amazonaws.com:11211',
|
79
|
+
'mycluster.0002.cache.amazonaws.com:11211',
|
80
|
+
'mycluster.0003.cache.amazonaws.com:11211']
|
81
|
+
expect(stub_endpoint).to have_received(:config)
|
82
|
+
expect(Dalli::Elasticache::AutoDiscovery::Endpoint).to have_received(:new).with(config_endpoint)
|
39
83
|
end
|
40
84
|
end
|
41
|
-
|
85
|
+
|
42
86
|
describe '#version' do
|
87
|
+
let(:mock_config) { instance_double(Dalli::Elasticache::AutoDiscovery::ConfigResponse) }
|
88
|
+
let(:version) { rand(1..20) }
|
89
|
+
|
90
|
+
before do
|
91
|
+
allow(cache.endpoint).to receive(:config).and_return(mock_config)
|
92
|
+
allow(mock_config).to receive(:version).and_return(version)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'delegates the call to the config on the endpoint' do
|
96
|
+
expect(cache.version).to eq(version)
|
97
|
+
expect(cache.endpoint).to have_received(:config)
|
98
|
+
expect(mock_config).to have_received(:version)
|
99
|
+
end
|
43
100
|
end
|
44
|
-
|
101
|
+
|
45
102
|
describe '#engine_version' do
|
103
|
+
let(:engine_version) { [Gem::Version.new('1.6.13'), Gem::Version.new('1.4.14')].sample }
|
104
|
+
|
105
|
+
before do
|
106
|
+
allow(cache.endpoint).to receive(:engine_version).and_return(engine_version)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'delegates the call to the endpoint' do
|
110
|
+
expect(cache.engine_version).to eq(engine_version)
|
111
|
+
expect(cache.endpoint).to have_received(:engine_version)
|
112
|
+
end
|
46
113
|
end
|
47
|
-
|
114
|
+
|
48
115
|
describe '#refresh' do
|
49
116
|
it 'clears endpoint configuration' do
|
50
117
|
stale_endpoint = cache.endpoint
|
51
|
-
cache.refresh.endpoint.
|
118
|
+
expect(cache.refresh.endpoint).not_to eq stale_endpoint
|
52
119
|
end
|
53
|
-
|
120
|
+
|
54
121
|
it 'builds endpoint with same configuration' do
|
55
122
|
stale_endpoint = cache.endpoint
|
56
123
|
cache.refresh
|
57
|
-
cache.endpoint.host.
|
58
|
-
cache.endpoint.port.
|
124
|
+
expect(cache.endpoint.host).to eq(stale_endpoint.host)
|
125
|
+
expect(cache.endpoint.port).to eq(stale_endpoint.port)
|
59
126
|
end
|
60
127
|
end
|
61
|
-
|
62
128
|
end
|
data/spec/endpoint_spec.rb
CHANGED
@@ -1,16 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'spec_helper'
|
2
4
|
|
3
5
|
describe 'Dalli::Elasticache::AutoDiscovery::Endpoint' do
|
4
6
|
let(:endpoint) do
|
5
|
-
Dalli::Elasticache::AutoDiscovery::Endpoint.new(
|
7
|
+
Dalli::Elasticache::AutoDiscovery::Endpoint.new(arg_string)
|
6
8
|
end
|
7
|
-
|
9
|
+
|
8
10
|
describe '.new' do
|
9
|
-
|
10
|
-
|
11
|
+
context 'when the string includes both host and port' do
|
12
|
+
let(:arg_string) { 'my-cluster.cfg.use1.cache.amazonaws.com:12345' }
|
13
|
+
|
14
|
+
it 'parses host' do
|
15
|
+
expect(endpoint.host).to eq 'my-cluster.cfg.use1.cache.amazonaws.com'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'parses port' do
|
19
|
+
expect(endpoint.port).to eq 12_345
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when the string includes only a host' do
|
24
|
+
let(:arg_string) { 'example.cfg.use1.cache.amazonaws.com' }
|
25
|
+
|
26
|
+
it 'parses host' do
|
27
|
+
expect(endpoint.host).to eq 'example.cfg.use1.cache.amazonaws.com'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'parses port' do
|
31
|
+
expect(endpoint.port).to eq 11_211
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when the string is nil' do
|
36
|
+
let(:arg_string) { nil }
|
37
|
+
|
38
|
+
it 'raises ArgumentError' do
|
39
|
+
expect do
|
40
|
+
endpoint
|
41
|
+
end.to raise_error ArgumentError, "Unable to parse configuration endpoint address - #{arg_string}"
|
42
|
+
end
|
11
43
|
end
|
12
|
-
|
13
|
-
|
44
|
+
|
45
|
+
context 'when the string contains disallowed characters in the host' do
|
46
|
+
let(:arg_string) { 'my-cluster?.cfg.use1.cache.amazonaws.com:12345' }
|
47
|
+
|
48
|
+
it 'raises ArgumentError' do
|
49
|
+
expect do
|
50
|
+
endpoint
|
51
|
+
end.to raise_error ArgumentError, "Unable to parse configuration endpoint address - #{arg_string}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when the string contains disallowed characters in the port' do
|
56
|
+
let(:arg_string) { 'my-cluster.cfg.use1.cache.amazonaws.com:1234a5' }
|
57
|
+
|
58
|
+
it 'raises ArgumentError' do
|
59
|
+
expect do
|
60
|
+
endpoint
|
61
|
+
end.to raise_error ArgumentError, "Unable to parse configuration endpoint address - #{arg_string}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when the string contains trailing characters' do
|
66
|
+
let(:arg_string) { 'my-cluster.cfg.use1.cache.amazonaws.com:12345abcd' }
|
67
|
+
|
68
|
+
it 'raises ArgumentError' do
|
69
|
+
expect do
|
70
|
+
endpoint
|
71
|
+
end.to raise_error ArgumentError, "Unable to parse configuration endpoint address - #{arg_string}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when the host in the string includes an underscore' do
|
76
|
+
let(:arg_string) { 'my_cluster.cfg.use1.cache.amazonaws.com:12345' }
|
77
|
+
|
78
|
+
it 'parses host' do
|
79
|
+
expect(endpoint.host).to eq 'my_cluster.cfg.use1.cache.amazonaws.com'
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'parses port' do
|
83
|
+
expect(endpoint.port).to eq 12_345
|
84
|
+
end
|
14
85
|
end
|
15
86
|
end
|
16
87
|
end
|
data/spec/node_spec.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'spec_helper'
|
4
|
+
|
5
|
+
describe 'Dalli::Elasticache::AutoDiscovery::Node' do
|
6
|
+
context 'when comparing with equals' do
|
7
|
+
let(:host1) { Faker::Internet.domain_name(subdomain: true) }
|
8
|
+
let(:ip1) { Faker::Internet.public_ip_v4_address }
|
9
|
+
let(:port1) { rand(1024..16_023) }
|
10
|
+
let(:host2) { Faker::Internet.domain_name(subdomain: true) }
|
11
|
+
let(:ip2) { Faker::Internet.public_ip_v4_address }
|
12
|
+
let(:port2) { rand(1024..16_023) }
|
13
|
+
|
14
|
+
let(:node1a) { Dalli::Elasticache::AutoDiscovery::Node.new(host1, ip1, port1) }
|
15
|
+
let(:node1b) { Dalli::Elasticache::AutoDiscovery::Node.new(host1, ip1, port1) }
|
16
|
+
|
17
|
+
let(:node_with_different_host) { Dalli::Elasticache::AutoDiscovery::Node.new(host2, ip1, port1) }
|
18
|
+
let(:node_with_different_ip) { Dalli::Elasticache::AutoDiscovery::Node.new(host1, ip2, port1) }
|
19
|
+
let(:node_with_different_port) { Dalli::Elasticache::AutoDiscovery::Node.new(host1, ip1, port2) }
|
20
|
+
|
21
|
+
it 'is equal to a value with the same values' do
|
22
|
+
expect(node1a).to eq(node1b)
|
23
|
+
expect(node1a.eql?(node1b)).to eq(true)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'is not equal to a value with any differing values' do
|
27
|
+
expect(node1a).not_to eq(node_with_different_host)
|
28
|
+
expect(node1a.eql?(node_with_different_host)).to eq(false)
|
29
|
+
expect(node1a).not_to eq(node_with_different_ip)
|
30
|
+
expect(node1a.eql?(node_with_different_ip)).to eq(false)
|
31
|
+
expect(node1a).not_to eq(node_with_different_port)
|
32
|
+
expect(node1a.eql?(node_with_different_port)).to eq(false)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when used as a hash key' do
|
37
|
+
let(:host1) { Faker::Internet.domain_name(subdomain: true) }
|
38
|
+
let(:ip1) { Faker::Internet.public_ip_v4_address }
|
39
|
+
let(:port1) { rand(1024..16_023) }
|
40
|
+
let(:host2) { Faker::Internet.domain_name(subdomain: true) }
|
41
|
+
let(:ip2) { Faker::Internet.public_ip_v4_address }
|
42
|
+
let(:port2) { rand(1024..16_023) }
|
43
|
+
|
44
|
+
let(:node1a) { Dalli::Elasticache::AutoDiscovery::Node.new(host1, ip1, port1) }
|
45
|
+
let(:node1b) { Dalli::Elasticache::AutoDiscovery::Node.new(host1, ip1, port1) }
|
46
|
+
|
47
|
+
let(:node_with_different_host) { Dalli::Elasticache::AutoDiscovery::Node.new(host2, ip1, port1) }
|
48
|
+
let(:node_with_different_ip) { Dalli::Elasticache::AutoDiscovery::Node.new(host1, ip2, port1) }
|
49
|
+
let(:node_with_different_port) { Dalli::Elasticache::AutoDiscovery::Node.new(host1, ip1, port2) }
|
50
|
+
|
51
|
+
let(:test_val) { 'abcd' }
|
52
|
+
let(:test_hash) do
|
53
|
+
{ node1a => test_val }
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'computes the same hash key' do
|
57
|
+
expect(node1a.hash).to eq(node1b.hash)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'matches when an equivalent object is used' do
|
61
|
+
expect(test_hash.key?(node1b)).to eq(true)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'does not match when an non-equivalent object is used' do
|
65
|
+
expect(test_hash.key?(node_with_different_host)).to eq(false)
|
66
|
+
expect(test_hash.key?(node_with_different_ip)).to eq(false)
|
67
|
+
expect(test_hash.key?(node_with_different_port)).to eq(false)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#to_s' do
|
72
|
+
let(:host) { Faker::Internet.domain_name(subdomain: true) }
|
73
|
+
let(:ip) { Faker::Internet.public_ip_v4_address }
|
74
|
+
let(:port) { rand(1024..16_023) }
|
75
|
+
|
76
|
+
let(:node) { Dalli::Elasticache::AutoDiscovery::Node.new(host, ip, port) }
|
77
|
+
|
78
|
+
it 'returns the expected string value' do
|
79
|
+
expect(node.to_s).to eq("#{host}:#{port}")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,12 +1,9 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
c.syntax = :should
|
11
|
-
end
|
12
|
-
end
|
5
|
+
require 'dalli/elasticache'
|
6
|
+
require 'securerandom'
|
7
|
+
require 'faker'
|
8
|
+
|
9
|
+
RSpec.configure
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'spec_helper'
|
4
|
+
|
5
|
+
describe 'Dalli::Elasticache::AutoDiscovery::StatsCommand' do
|
6
|
+
let(:host) { 'example.com' }
|
7
|
+
let(:port) { 12_345 }
|
8
|
+
let(:command) { Dalli::Elasticache::AutoDiscovery::StatsCommand.new(host, port) }
|
9
|
+
let(:engine_version) { ['1.4.5', '1.4.14', '1.5.6', '1.6.10'].sample }
|
10
|
+
let(:cmd) { "stats\r\n" }
|
11
|
+
|
12
|
+
let(:socket_response_lines) do
|
13
|
+
[
|
14
|
+
"STAT pid 1\r\n",
|
15
|
+
"STAT uptime 68717\r\n",
|
16
|
+
"STAT time 1398885375\r\n",
|
17
|
+
"STAT version #{engine_version}\r\n",
|
18
|
+
"STAT libevent 1.4.13-stable\r\n",
|
19
|
+
"STAT pointer_size 64\r\n",
|
20
|
+
"STAT rusage_user 0.136008\r\n",
|
21
|
+
"STAT rusage_system 0.424026\r\n",
|
22
|
+
"STAT curr_connections 5\r\n",
|
23
|
+
"STAT total_connections 1159\r\n",
|
24
|
+
"STAT connection_structures 6\r\n",
|
25
|
+
"STAT reserved_fds 5\r\n",
|
26
|
+
"STAT cmd_get 0\r\n",
|
27
|
+
"STAT cmd_set 0\r\n",
|
28
|
+
"STAT cmd_flush 0\r\n",
|
29
|
+
"STAT cmd_touch 0\r\n",
|
30
|
+
"STAT cmd_config_get 4582\r\n",
|
31
|
+
"STAT cmd_config_set 2\r\n",
|
32
|
+
"STAT get_hits 0\r\n",
|
33
|
+
"STAT get_misses 0\r\n",
|
34
|
+
"STAT delete_misses 0\r\n",
|
35
|
+
"STAT delete_hits 0\r\n",
|
36
|
+
"STAT incr_misses 0\r\n",
|
37
|
+
"STAT incr_hits 0\r\n",
|
38
|
+
"STAT decr_misses 0\r\n",
|
39
|
+
"STAT decr_hits 0\r\n",
|
40
|
+
"STAT cas_misses 0\r\n",
|
41
|
+
"STAT cas_hits 0\r\n",
|
42
|
+
"STAT cas_badval 0\r\n",
|
43
|
+
"STAT touch_hits 0\r\n",
|
44
|
+
"STAT touch_misses 0\r\n",
|
45
|
+
"STAT auth_cmds 0\r\n",
|
46
|
+
"STAT auth_errors 0\r\n",
|
47
|
+
"STAT bytes_read 189356\r\n",
|
48
|
+
"STAT bytes_written 2906615\r\n",
|
49
|
+
"STAT limit_maxbytes 209715200\r\n",
|
50
|
+
"STAT accepting_conns 1\r\n",
|
51
|
+
"STAT listen_disabled_num 0\r\n",
|
52
|
+
"STAT threads 1\r\n",
|
53
|
+
"STAT conn_yields 0\r\n",
|
54
|
+
"STAT curr_config 1\r\n",
|
55
|
+
"STAT hash_power_level 16\r\n",
|
56
|
+
"STAT hash_bytes 524288\r\n",
|
57
|
+
"STAT hash_is_expanding 0\r\n",
|
58
|
+
"STAT expired_unfetched 0\r\n",
|
59
|
+
"STAT evicted_unfetched 0\r\n",
|
60
|
+
"STAT bytes 0\r\n",
|
61
|
+
"STAT curr_items 0\r\n",
|
62
|
+
"STAT total_items 0\r\n",
|
63
|
+
"STAT evictions 0\r\n",
|
64
|
+
"STAT reclaimed 0\r\n",
|
65
|
+
"END\r\n"
|
66
|
+
]
|
67
|
+
end
|
68
|
+
|
69
|
+
let(:mock_socket) { instance_double(TCPSocket) }
|
70
|
+
|
71
|
+
before do
|
72
|
+
allow(TCPSocket).to receive(:new).with(host, port).and_return(mock_socket)
|
73
|
+
allow(mock_socket).to receive(:close)
|
74
|
+
allow(mock_socket).to receive(:puts).with(cmd)
|
75
|
+
allow(mock_socket).to receive(:readline).and_return(*socket_response_lines)
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when the socket returns a valid response' do
|
79
|
+
before do
|
80
|
+
allow(mock_socket).to receive(:readline).and_return(*socket_response_lines)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'sends the command and parses out the engine version' do
|
84
|
+
response = command.response
|
85
|
+
expect(response.engine_version).to eq(engine_version)
|
86
|
+
expect(mock_socket).to have_received(:close)
|
87
|
+
expect(mock_socket).to have_received(:puts).with(cmd)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|