dalli-elasticache 0.1.1 → 1.0.1
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 +5 -13
- data/README.md +36 -21
- data/Rakefile +7 -4
- 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 +42 -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 +106 -23
- 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 +115 -29
@@ -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,45 +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
|
+
|
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
|
26
|
+
let(:response) { Dalli::Elasticache::AutoDiscovery::ConfigResponse.new(config_text) }
|
27
|
+
|
13
28
|
describe '.new' do
|
14
29
|
it 'builds endpoint' do
|
15
|
-
cache.endpoint.host.
|
16
|
-
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
|
17
32
|
end
|
18
|
-
|
33
|
+
|
19
34
|
it 'stores Dalli options' do
|
20
|
-
cache.options[:expires_in].
|
21
|
-
cache.options[:namespace].
|
22
|
-
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
|
23
38
|
end
|
24
39
|
end
|
25
|
-
|
40
|
+
|
26
41
|
describe '#client' do
|
27
|
-
|
28
|
-
|
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
|
29
66
|
end
|
30
|
-
|
67
|
+
|
31
68
|
describe '#servers' do
|
32
|
-
|
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
|
76
|
+
|
77
|
+
it 'lists addresses and ports' do
|
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)
|
83
|
+
end
|
33
84
|
end
|
34
|
-
|
85
|
+
|
35
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
|
36
100
|
end
|
37
|
-
|
101
|
+
|
38
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
|
39
113
|
end
|
40
|
-
|
114
|
+
|
41
115
|
describe '#refresh' do
|
42
|
-
it 'clears endpoint configuration'
|
116
|
+
it 'clears endpoint configuration' do
|
117
|
+
stale_endpoint = cache.endpoint
|
118
|
+
expect(cache.refresh.endpoint).not_to eq stale_endpoint
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'builds endpoint with same configuration' do
|
122
|
+
stale_endpoint = cache.endpoint
|
123
|
+
cache.refresh
|
124
|
+
expect(cache.endpoint.host).to eq(stale_endpoint.host)
|
125
|
+
expect(cache.endpoint.port).to eq(stale_endpoint.port)
|
126
|
+
end
|
43
127
|
end
|
44
|
-
|
45
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
|