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.
@@ -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 mycluster.0002.cache.amazonaws.com|10.112.21.2|11211 mycluster.0003.cache.amazonaws.com|10.112.21.3|11211\n\r\n"
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.should == 12
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{|s| s[:host]}.should == [
18
- "mycluster.0001.cache.amazonaws.com",
19
- "mycluster.0002.cache.amazonaws.com",
20
- "mycluster.0003.cache.amazonaws.com"
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{|s| s[:ip]}.should == ["10.112.21.1", "10.112.21.2", "10.112.21.3"]
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{|s| s[:port]}.should == [11211, 11211, 11211]
33
+ expect(response.nodes.map(&:port)).to eq [11_211, 11_211, 11_211]
30
34
  end
31
35
  end
32
36
  end
@@ -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(:cache) do
5
- options = {
6
- :expires_in => 24*60*60,
7
- :namespace => "my_app",
8
- :compress => true
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.should == "my-cluster.cfg.use1.cache.amazonaws.com"
16
- cache.endpoint.port.should == 11211
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].should == 24*60*60
21
- cache.options[:namespace].should == "my_app"
22
- cache.options[:compress].should == true
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
- it 'builds with node list'
28
- it 'builds with options'
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
- it 'lists addresses and ports'
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
@@ -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("my-cluster.cfg.use1.cache.amazonaws.com:11211")
7
+ Dalli::Elasticache::AutoDiscovery::Endpoint.new(arg_string)
6
8
  end
7
-
9
+
8
10
  describe '.new' do
9
- it 'parses host' do
10
- endpoint.host.should == "my-cluster.cfg.use1.cache.amazonaws.com"
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
- it 'parses port' do
13
- endpoint.port.should == 11211
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
- require "bundler/setup"
1
+ # frozen_string_literal: true
2
2
 
3
- require "dalli/elasticache"
3
+ require 'bundler/setup'
4
4
 
5
- RSpec.configure do |config|
6
- config.expect_with :rspec do |c|
7
- c.syntax = :should
8
- end
9
- config.mock_with :rspec do |c|
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