dalli-elasticache 1.0.1 → 2.0.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 +4 -4
- data/README.md +2 -2
- data/lib/dalli/elasticache/auto_discovery/base_command.rb +17 -4
- data/lib/dalli/elasticache/auto_discovery/config_command.rb +0 -22
- data/lib/dalli/elasticache/auto_discovery/config_response.rb +3 -3
- data/lib/dalli/elasticache/auto_discovery/endpoint.rb +6 -5
- data/lib/dalli/elasticache/auto_discovery/stats_response.rb +1 -1
- data/lib/dalli/elasticache/version.rb +1 -1
- data/lib/dalli/elasticache.rb +11 -5
- metadata +7 -124
- data/spec/config_command_spec.rb +0 -101
- data/spec/config_response_spec.rb +0 -36
- data/spec/elasticache_spec.rb +0 -128
- data/spec/endpoint_spec.rb +0 -87
- data/spec/node_spec.rb +0 -82
- data/spec/spec_helper.rb +0 -9
- data/spec/stats_command_spec.rb +0 -90
- data/spec/stats_response_spec.rb +0 -117
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 66afce9165ca020c9c46d25f12901919968d33ec9de15be287a9f589497a042e
|
|
4
|
+
data.tar.gz: e67a94f65b45ecaf034ba6bfd67c574c3275100d43b8f893d52181606dfdeb1e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 92399afd4065a1bdb8f387eb6e04d47152c3e4e2e25fe8449713258409d84986014c2c71ad67a0aa90d8a2bd8a3df9721aca6862ac456c908d1fee4901b4465f
|
|
7
|
+
data.tar.gz: 379dce4897d563f6811133aaef02c724da76a0bc6f31973b324241d913c5dae2bb53aa15f0536518de6f7e42d1526ff3f3efbfc83f13fc7d3610cff5277d44b0
|
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Dalli ElastiCache [](http://badge.fury.io/rb/dalli-elasticache) [](https://github.com/ktheory/dalli-elasticache/actions/workflows/tests.yml) [](https://codeclimate.com/github/ktheory/dalli-elasticache)
|
|
2
2
|
=================
|
|
3
3
|
|
|
4
|
-
Use [AWS ElastiCache AutoDiscovery](
|
|
4
|
+
Use [AWS ElastiCache AutoDiscovery](https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/AutoDiscovery.html) or [Google Cloud MemoryStore Auto Discovery](https://cloud.google.com/memorystore/docs/memcached/using-auto-discovery) to automatically configure your [Dalli memcached client](https://github.com/petergoldstein/dalli) with all the nodes in your cluster.
|
|
5
5
|
|
|
6
6
|
Installation
|
|
7
7
|
------------
|
|
@@ -49,7 +49,7 @@ Please see [here](https://github.com/petergoldstein/dalli/wiki/Using-Dalli-with-
|
|
|
49
49
|
Using Dalli ElastiCache with a Dalli Client
|
|
50
50
|
------------
|
|
51
51
|
|
|
52
|
-
To initialize a Dalli Client
|
|
52
|
+
To initialize a Dalli Client for all the nodes of a cluster, one simply needs to pass the configuration endpoint and any options for the Dalli Client into the `Dalli::ElastiCache` initializer. Then one can use the methods on the `Dalli::ElastiCache` object to generate an appropriately configured `Dalli::Client`or to get information about the cluster.
|
|
53
53
|
|
|
54
54
|
```ruby
|
|
55
55
|
config_endpoint = "aaron-scratch.vfdnac.cfg.use1.cache.amazonaws.com:11211"
|
|
@@ -8,18 +8,19 @@ module Dalli
|
|
|
8
8
|
# command. Contains the network logic.
|
|
9
9
|
##
|
|
10
10
|
class BaseCommand
|
|
11
|
-
attr_reader :host, :port
|
|
11
|
+
attr_reader :host, :port, :timeout
|
|
12
12
|
|
|
13
|
-
def initialize(host, port)
|
|
13
|
+
def initialize(host, port, timeout = nil)
|
|
14
14
|
@host = host
|
|
15
15
|
@port = port
|
|
16
|
+
@timeout = timeout
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
# Send an ASCII command to the endpoint
|
|
19
20
|
#
|
|
20
21
|
# Returns the raw response as a String
|
|
21
22
|
def send_command
|
|
22
|
-
socket =
|
|
23
|
+
socket = ::Socket.tcp(@host, @port, connect_timeout: timeout)
|
|
23
24
|
begin
|
|
24
25
|
socket.puts command
|
|
25
26
|
response_from_socket(socket)
|
|
@@ -30,12 +31,24 @@ module Dalli
|
|
|
30
31
|
|
|
31
32
|
def response_from_socket(socket)
|
|
32
33
|
data = +''
|
|
33
|
-
|
|
34
|
+
loop do
|
|
35
|
+
wait_for_data(socket)
|
|
36
|
+
line = socket.readline
|
|
37
|
+
break if line.include?('END')
|
|
38
|
+
|
|
34
39
|
data << line
|
|
35
40
|
end
|
|
36
41
|
|
|
37
42
|
data
|
|
38
43
|
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def wait_for_data(socket)
|
|
48
|
+
return unless timeout
|
|
49
|
+
|
|
50
|
+
raise Timeout::Error, "Auto discovery read timed out after #{timeout}s" unless socket.wait_readable(timeout)
|
|
51
|
+
end
|
|
39
52
|
end
|
|
40
53
|
end
|
|
41
54
|
end
|
|
@@ -8,37 +8,15 @@ module Dalli
|
|
|
8
8
|
# extract the list of nodes and determine if that list of nodes has changed.
|
|
9
9
|
##
|
|
10
10
|
class ConfigCommand < BaseCommand
|
|
11
|
-
attr_reader :engine_version
|
|
12
|
-
|
|
13
11
|
CONFIG_COMMAND = "config get cluster\r\n"
|
|
14
12
|
|
|
15
|
-
# Legacy command for version < 1.4.14
|
|
16
|
-
LEGACY_CONFIG_COMMAND = "get AmazonElastiCache:cluster\r\n"
|
|
17
|
-
|
|
18
|
-
def initialize(host, port, engine_version)
|
|
19
|
-
super(host, port)
|
|
20
|
-
@engine_version = engine_version
|
|
21
|
-
end
|
|
22
|
-
|
|
23
13
|
def response
|
|
24
14
|
ConfigResponse.new(send_command)
|
|
25
15
|
end
|
|
26
16
|
|
|
27
17
|
def command
|
|
28
|
-
return LEGACY_CONFIG_COMMAND if legacy_config?
|
|
29
|
-
|
|
30
18
|
CONFIG_COMMAND
|
|
31
19
|
end
|
|
32
|
-
|
|
33
|
-
def legacy_config?
|
|
34
|
-
return false unless engine_version
|
|
35
|
-
return false if engine_version.casecmp('unknown').zero?
|
|
36
|
-
|
|
37
|
-
Gem::Version.new(engine_version) < Gem::Version.new('1.4.14')
|
|
38
|
-
rescue ArgumentError
|
|
39
|
-
# Just assume false if we can't parse the engine_version
|
|
40
|
-
false
|
|
41
|
-
end
|
|
42
20
|
end
|
|
43
21
|
end
|
|
44
22
|
end
|
|
@@ -12,11 +12,11 @@ module Dalli
|
|
|
12
12
|
attr_reader :text
|
|
13
13
|
|
|
14
14
|
# Matches the version line of the response
|
|
15
|
-
VERSION_REGEX = /^(\d+)\r?\n
|
|
15
|
+
VERSION_REGEX = /^(\d+)\r?\n/
|
|
16
16
|
|
|
17
17
|
# Matches strings like "my-cluster.001.cache.aws.com|10.154.182.29|11211"
|
|
18
|
-
NODE_REGEX = /(([-.a-zA-Z0-9]+)\|(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)\|(\d+))
|
|
19
|
-
NODE_LIST_REGEX = /^(#{NODE_REGEX}\s*)
|
|
18
|
+
NODE_REGEX = /(([-.a-zA-Z0-9]+)\|(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)\|(\d+))/
|
|
19
|
+
NODE_LIST_REGEX = /^(#{NODE_REGEX}\s*)+$/
|
|
20
20
|
|
|
21
21
|
def initialize(response_text)
|
|
22
22
|
@text = response_text.to_s
|
|
@@ -12,11 +12,12 @@ module Dalli
|
|
|
12
12
|
# Endpoint configuration
|
|
13
13
|
attr_reader :host, :port
|
|
14
14
|
|
|
15
|
-
# Matches
|
|
16
|
-
ENDPOINT_REGEX = /^([-_.a-zA-Z0-9]
|
|
15
|
+
# Matches DNS/IPv4 like "my-host.cache.aws.com:11211" or bracketed IPv6 like "[::1]:11211"
|
|
16
|
+
ENDPOINT_REGEX = /^([-_.a-zA-Z0-9]+|\[[a-fA-F0-9:]+\])(?::(\d+))?$/
|
|
17
17
|
|
|
18
|
-
def initialize(addr)
|
|
18
|
+
def initialize(addr, timeout: nil)
|
|
19
19
|
@host, @port = parse_endpoint_address(addr)
|
|
20
|
+
@timeout = timeout
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
DEFAULT_PORT = 11_211
|
|
@@ -29,12 +30,12 @@ module Dalli
|
|
|
29
30
|
|
|
30
31
|
# A cached ElastiCache::StatsResponse
|
|
31
32
|
def stats
|
|
32
|
-
@stats ||= StatsCommand.new(@host, @port).response
|
|
33
|
+
@stats ||= StatsCommand.new(@host, @port, @timeout).response
|
|
33
34
|
end
|
|
34
35
|
|
|
35
36
|
# A cached ElastiCache::ConfigResponse
|
|
36
37
|
def config
|
|
37
|
-
@config ||= ConfigCommand.new(@host, @port,
|
|
38
|
+
@config ||= ConfigCommand.new(@host, @port, @timeout).response
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
# The memcached engine version
|
|
@@ -13,7 +13,7 @@ module Dalli
|
|
|
13
13
|
attr_reader :text
|
|
14
14
|
|
|
15
15
|
# Matches the version line of the response
|
|
16
|
-
VERSION_REGEX = /^STAT version ([0-9.]+|unknown)\s*/i
|
|
16
|
+
VERSION_REGEX = /^STAT version ([0-9.]+|unknown)\s*/i
|
|
17
17
|
|
|
18
18
|
def initialize(response_text)
|
|
19
19
|
@text = response_text.to_s
|
data/lib/dalli/elasticache.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'dalli'
|
|
4
4
|
require 'socket'
|
|
5
|
+
require 'timeout'
|
|
5
6
|
require_relative 'elasticache/version'
|
|
6
7
|
require_relative 'elasticache/auto_discovery/endpoint'
|
|
7
8
|
require_relative 'elasticache/auto_discovery/base_command'
|
|
@@ -21,6 +22,8 @@ module Dalli
|
|
|
21
22
|
# distributes cached items consistently over the nodes.
|
|
22
23
|
##
|
|
23
24
|
class ElastiCache
|
|
25
|
+
DEFAULT_TIMEOUT = 5
|
|
26
|
+
|
|
24
27
|
attr_reader :endpoint, :options
|
|
25
28
|
|
|
26
29
|
##
|
|
@@ -28,13 +31,16 @@ module Dalli
|
|
|
28
31
|
#
|
|
29
32
|
# config_endpoint - a String containing the host and (optionally) port of the
|
|
30
33
|
# configuration endpoint for the cluster. If not specified the port will
|
|
31
|
-
# default to 11211. The host must be either a DNS name
|
|
32
|
-
#
|
|
34
|
+
# default to 11211. The host must be either a DNS name, an IPv4 address, or
|
|
35
|
+
# a bracketed IPv6 address.
|
|
33
36
|
# dalli_options - a set of options passed to the Dalli::Client that is returned
|
|
34
37
|
# by the client method. Otherwise unused.
|
|
38
|
+
# timeout: - connect and read timeout in seconds for auto-discovery TCP calls.
|
|
39
|
+
# Defaults to 5 seconds.
|
|
35
40
|
##
|
|
36
|
-
def initialize(config_endpoint, dalli_options = {})
|
|
37
|
-
@
|
|
41
|
+
def initialize(config_endpoint, dalli_options = {}, timeout: DEFAULT_TIMEOUT)
|
|
42
|
+
@timeout = timeout
|
|
43
|
+
@endpoint = Dalli::Elasticache::AutoDiscovery::Endpoint.new(config_endpoint, timeout:)
|
|
38
44
|
@options = dalli_options
|
|
39
45
|
end
|
|
40
46
|
|
|
@@ -66,7 +72,7 @@ module Dalli
|
|
|
66
72
|
# Clear all cached data from the cluster endpoint
|
|
67
73
|
def refresh
|
|
68
74
|
config_endpoint = "#{endpoint.host}:#{endpoint.port}"
|
|
69
|
-
@endpoint = Dalli::Elasticache::AutoDiscovery::Endpoint.new(config_endpoint)
|
|
75
|
+
@endpoint = Dalli::Elasticache::AutoDiscovery::Endpoint.new(config_endpoint, timeout: @timeout)
|
|
70
76
|
|
|
71
77
|
self
|
|
72
78
|
end
|
metadata
CHANGED
|
@@ -1,129 +1,30 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dalli-elasticache
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aaron Suggs
|
|
8
8
|
- Zach Millman
|
|
9
9
|
- Peter M. Goldstein
|
|
10
|
-
autorequire:
|
|
11
10
|
bindir: bin
|
|
12
11
|
cert_chain: []
|
|
13
|
-
date:
|
|
12
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
14
13
|
dependencies:
|
|
15
|
-
- !ruby/object:Gem::Dependency
|
|
16
|
-
name: faker
|
|
17
|
-
requirement: !ruby/object:Gem::Requirement
|
|
18
|
-
requirements:
|
|
19
|
-
- - "~>"
|
|
20
|
-
- !ruby/object:Gem::Version
|
|
21
|
-
version: '2.19'
|
|
22
|
-
type: :development
|
|
23
|
-
prerelease: false
|
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
-
requirements:
|
|
26
|
-
- - "~>"
|
|
27
|
-
- !ruby/object:Gem::Version
|
|
28
|
-
version: '2.19'
|
|
29
|
-
- !ruby/object:Gem::Dependency
|
|
30
|
-
name: rake
|
|
31
|
-
requirement: !ruby/object:Gem::Requirement
|
|
32
|
-
requirements:
|
|
33
|
-
- - ">="
|
|
34
|
-
- !ruby/object:Gem::Version
|
|
35
|
-
version: '13.0'
|
|
36
|
-
type: :development
|
|
37
|
-
prerelease: false
|
|
38
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
39
|
-
requirements:
|
|
40
|
-
- - ">="
|
|
41
|
-
- !ruby/object:Gem::Version
|
|
42
|
-
version: '13.0'
|
|
43
|
-
- !ruby/object:Gem::Dependency
|
|
44
|
-
name: rspec
|
|
45
|
-
requirement: !ruby/object:Gem::Requirement
|
|
46
|
-
requirements:
|
|
47
|
-
- - "~>"
|
|
48
|
-
- !ruby/object:Gem::Version
|
|
49
|
-
version: '3.10'
|
|
50
|
-
type: :development
|
|
51
|
-
prerelease: false
|
|
52
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
53
|
-
requirements:
|
|
54
|
-
- - "~>"
|
|
55
|
-
- !ruby/object:Gem::Version
|
|
56
|
-
version: '3.10'
|
|
57
|
-
- !ruby/object:Gem::Dependency
|
|
58
|
-
name: rubocop
|
|
59
|
-
requirement: !ruby/object:Gem::Requirement
|
|
60
|
-
requirements:
|
|
61
|
-
- - "~>"
|
|
62
|
-
- !ruby/object:Gem::Version
|
|
63
|
-
version: '1.0'
|
|
64
|
-
type: :development
|
|
65
|
-
prerelease: false
|
|
66
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
67
|
-
requirements:
|
|
68
|
-
- - "~>"
|
|
69
|
-
- !ruby/object:Gem::Version
|
|
70
|
-
version: '1.0'
|
|
71
|
-
- !ruby/object:Gem::Dependency
|
|
72
|
-
name: rubocop-performance
|
|
73
|
-
requirement: !ruby/object:Gem::Requirement
|
|
74
|
-
requirements:
|
|
75
|
-
- - ">="
|
|
76
|
-
- !ruby/object:Gem::Version
|
|
77
|
-
version: '0'
|
|
78
|
-
type: :development
|
|
79
|
-
prerelease: false
|
|
80
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
81
|
-
requirements:
|
|
82
|
-
- - ">="
|
|
83
|
-
- !ruby/object:Gem::Version
|
|
84
|
-
version: '0'
|
|
85
|
-
- !ruby/object:Gem::Dependency
|
|
86
|
-
name: rubocop-rake
|
|
87
|
-
requirement: !ruby/object:Gem::Requirement
|
|
88
|
-
requirements:
|
|
89
|
-
- - ">="
|
|
90
|
-
- !ruby/object:Gem::Version
|
|
91
|
-
version: '0'
|
|
92
|
-
type: :development
|
|
93
|
-
prerelease: false
|
|
94
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
95
|
-
requirements:
|
|
96
|
-
- - ">="
|
|
97
|
-
- !ruby/object:Gem::Version
|
|
98
|
-
version: '0'
|
|
99
|
-
- !ruby/object:Gem::Dependency
|
|
100
|
-
name: rubocop-rspec
|
|
101
|
-
requirement: !ruby/object:Gem::Requirement
|
|
102
|
-
requirements:
|
|
103
|
-
- - ">="
|
|
104
|
-
- !ruby/object:Gem::Version
|
|
105
|
-
version: '0'
|
|
106
|
-
type: :development
|
|
107
|
-
prerelease: false
|
|
108
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
109
|
-
requirements:
|
|
110
|
-
- - ">="
|
|
111
|
-
- !ruby/object:Gem::Version
|
|
112
|
-
version: '0'
|
|
113
14
|
- !ruby/object:Gem::Dependency
|
|
114
15
|
name: dalli
|
|
115
16
|
requirement: !ruby/object:Gem::Requirement
|
|
116
17
|
requirements:
|
|
117
18
|
- - ">="
|
|
118
19
|
- !ruby/object:Gem::Version
|
|
119
|
-
version:
|
|
20
|
+
version: 5.0.0
|
|
120
21
|
type: :runtime
|
|
121
22
|
prerelease: false
|
|
122
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
123
24
|
requirements:
|
|
124
25
|
- - ">="
|
|
125
26
|
- !ruby/object:Gem::Version
|
|
126
|
-
version:
|
|
27
|
+
version: 5.0.0
|
|
127
28
|
description: |2
|
|
128
29
|
This gem provides an interface for fetching cluster information from an AWS
|
|
129
30
|
ElastiCache AutoDiscovery server and configuring a Dalli client to connect
|
|
@@ -148,20 +49,11 @@ files:
|
|
|
148
49
|
- lib/dalli/elasticache/auto_discovery/stats_command.rb
|
|
149
50
|
- lib/dalli/elasticache/auto_discovery/stats_response.rb
|
|
150
51
|
- lib/dalli/elasticache/version.rb
|
|
151
|
-
- spec/config_command_spec.rb
|
|
152
|
-
- spec/config_response_spec.rb
|
|
153
|
-
- spec/elasticache_spec.rb
|
|
154
|
-
- spec/endpoint_spec.rb
|
|
155
|
-
- spec/node_spec.rb
|
|
156
|
-
- spec/spec_helper.rb
|
|
157
|
-
- spec/stats_command_spec.rb
|
|
158
|
-
- spec/stats_response_spec.rb
|
|
159
52
|
homepage: http://github.com/ktheory/dalli-elasticache
|
|
160
53
|
licenses:
|
|
161
54
|
- MIT
|
|
162
55
|
metadata:
|
|
163
56
|
rubygems_mfa_required: 'true'
|
|
164
|
-
post_install_message:
|
|
165
57
|
rdoc_options:
|
|
166
58
|
- "--charset=UTF-8"
|
|
167
59
|
require_paths:
|
|
@@ -170,23 +62,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
170
62
|
requirements:
|
|
171
63
|
- - ">="
|
|
172
64
|
- !ruby/object:Gem::Version
|
|
173
|
-
version:
|
|
65
|
+
version: 3.3.0
|
|
174
66
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
67
|
requirements:
|
|
176
68
|
- - ">="
|
|
177
69
|
- !ruby/object:Gem::Version
|
|
178
70
|
version: 1.3.5
|
|
179
71
|
requirements: []
|
|
180
|
-
rubygems_version:
|
|
181
|
-
signing_key:
|
|
72
|
+
rubygems_version: 4.0.6
|
|
182
73
|
specification_version: 4
|
|
183
74
|
summary: Configure Dalli clients with ElastiCache's AutoDiscovery
|
|
184
|
-
test_files:
|
|
185
|
-
- spec/config_command_spec.rb
|
|
186
|
-
- spec/config_response_spec.rb
|
|
187
|
-
- spec/elasticache_spec.rb
|
|
188
|
-
- spec/endpoint_spec.rb
|
|
189
|
-
- spec/node_spec.rb
|
|
190
|
-
- spec/spec_helper.rb
|
|
191
|
-
- spec/stats_command_spec.rb
|
|
192
|
-
- spec/stats_response_spec.rb
|
|
75
|
+
test_files: []
|
data/spec/config_command_spec.rb
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
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,36 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe 'Dalli::Elasticache::AutoDiscovery::ConfigResponse' do
|
|
6
|
-
let :response do
|
|
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"
|
|
10
|
-
Dalli::Elasticache::AutoDiscovery::ConfigResponse.new(text)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
describe '#version' do
|
|
14
|
-
it 'parses version' do
|
|
15
|
-
expect(response.version).to eq 12
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
describe '#nodes' do
|
|
20
|
-
it 'parses hosts' do
|
|
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'
|
|
25
|
-
]
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it 'parses ip addresses' do
|
|
29
|
-
expect(response.nodes.map(&:ip)).to eq ['10.112.21.1', '10.112.21.2', '10.112.21.3']
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it 'parses ports' do
|
|
33
|
-
expect(response.nodes.map(&:port)).to eq [11_211, 11_211, 11_211]
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
data/spec/elasticache_spec.rb
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe 'Dalli::ElastiCache::Endpoint' do
|
|
6
|
-
let(:dalli_options) do
|
|
7
|
-
{
|
|
8
|
-
expires_in: 24 * 60 * 60,
|
|
9
|
-
namespace: 'my_app',
|
|
10
|
-
compress: true
|
|
11
|
-
}
|
|
12
|
-
end
|
|
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
|
-
|
|
28
|
-
describe '.new' do
|
|
29
|
-
it 'builds endpoint' do
|
|
30
|
-
expect(cache.endpoint.host).to eq 'my-cluster.cfg.use1.cache.amazonaws.com'
|
|
31
|
-
expect(cache.endpoint.port).to eq 11_211
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
it 'stores Dalli options' do
|
|
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
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
describe '#client' do
|
|
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
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
describe '#servers' do
|
|
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
|
|
84
|
-
end
|
|
85
|
-
|
|
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
|
|
100
|
-
end
|
|
101
|
-
|
|
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
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
describe '#refresh' do
|
|
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
|
|
127
|
-
end
|
|
128
|
-
end
|
data/spec/endpoint_spec.rb
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe 'Dalli::Elasticache::AutoDiscovery::Endpoint' do
|
|
6
|
-
let(:endpoint) do
|
|
7
|
-
Dalli::Elasticache::AutoDiscovery::Endpoint.new(arg_string)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
describe '.new' do
|
|
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
|
|
43
|
-
end
|
|
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
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
data/spec/node_spec.rb
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
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
DELETED
data/spec/stats_command_spec.rb
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
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
|
data/spec/stats_response_spec.rb
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe 'Dalli::Elasticache::AutoDiscovery::StatsResponse' do
|
|
6
|
-
let(:response) { Dalli::Elasticache::AutoDiscovery::StatsResponse.new(response_text) }
|
|
7
|
-
|
|
8
|
-
describe '#engine_version' do
|
|
9
|
-
context 'when the version number is a number' do
|
|
10
|
-
let(:engine_version) { ['1.4.14', '1.5.6', '1.6.10'].sample }
|
|
11
|
-
|
|
12
|
-
context 'when the response with the version stat only includes the version number' do
|
|
13
|
-
let(:response_text) do
|
|
14
|
-
"STAT pid 1\r\nSTAT uptime 68717\r\nSTAT time 1398885375\r\n"\
|
|
15
|
-
"STAT version #{engine_version}\r\n"\
|
|
16
|
-
"STAT libevent 1.4.13-stable\r\nSTAT pointer_size 64\r\nSTAT rusage_user 0.136008\r\n"\
|
|
17
|
-
"STAT rusage_system 0.424026\r\nSTAT curr_connections 5\r\nSTAT total_connections 1159\r\n"\
|
|
18
|
-
"STAT connection_structures 6\r\nSTAT reserved_fds 5\r\nSTAT cmd_get 0\r\n"\
|
|
19
|
-
"STAT cmd_set 0\r\nSTAT cmd_flush 0\r\nSTAT cmd_touch 0\r\nSTAT cmd_config_get 4582\r\n"\
|
|
20
|
-
"STAT cmd_config_set 2\r\nSTAT get_hits 0\r\nSTAT get_misses 0\r\nSTAT delete_misses 0\r\n"\
|
|
21
|
-
"STAT delete_hits 0\r\nSTAT incr_misses 0\r\nSTAT incr_hits 0\r\nSTAT decr_misses 0\r\n"\
|
|
22
|
-
"STAT decr_hits 0\r\nSTAT cas_misses 0\r\nSTAT cas_hits 0\r\nSTAT cas_badval 0\r\n"\
|
|
23
|
-
"STAT touch_hits 0\r\nSTAT touch_misses 0\r\nSTAT auth_cmds 0\r\nSTAT auth_errors 0\r\n"\
|
|
24
|
-
"STAT bytes_read 189356\r\nSTAT bytes_written 2906615\r\nSTAT limit_maxbytes 209715200\r\n"\
|
|
25
|
-
"STAT accepting_conns 1\r\nSTAT listen_disabled_num 0\r\nSTAT threads 1\r\n"\
|
|
26
|
-
"STAT conn_yields 0\r\nSTAT curr_config 1\r\nSTAT hash_power_level 16\r\n"\
|
|
27
|
-
"STAT hash_bytes 524288\r\nSTAT hash_is_expanding 0\r\nSTAT expired_unfetched 0\r\n"\
|
|
28
|
-
"STAT evicted_unfetched 0\r\nSTAT bytes 0\r\nSTAT curr_items 0\r\nSTAT total_items 0\r\n"\
|
|
29
|
-
"STAT evictions 0\r\nSTAT reclaimed 0\r\n"
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it 'parses out the engine version' do
|
|
33
|
-
expect(response.engine_version).to eq engine_version
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
context 'when the response with the version stat includes the version number and trailing text' do
|
|
38
|
-
let(:response_text) do
|
|
39
|
-
"STAT pid 1\r\nSTAT uptime 68717\r\nSTAT time 1398885375\r\n"\
|
|
40
|
-
"STAT version #{engine_version} #{SecureRandom.hex(5)}\r\n"\
|
|
41
|
-
"STAT libevent 1.4.13-stable\r\nSTAT pointer_size 64\r\nSTAT rusage_user 0.136008\r\n"\
|
|
42
|
-
"STAT rusage_system 0.424026\r\nSTAT curr_connections 5\r\nSTAT total_connections 1159\r\n"\
|
|
43
|
-
"STAT connection_structures 6\r\nSTAT reserved_fds 5\r\nSTAT cmd_get 0\r\n"\
|
|
44
|
-
"STAT cmd_set 0\r\nSTAT cmd_flush 0\r\nSTAT cmd_touch 0\r\nSTAT cmd_config_get 4582\r\n"\
|
|
45
|
-
"STAT cmd_config_set 2\r\nSTAT get_hits 0\r\nSTAT get_misses 0\r\nSTAT delete_misses 0\r\n"\
|
|
46
|
-
"STAT delete_hits 0\r\nSTAT incr_misses 0\r\nSTAT incr_hits 0\r\nSTAT decr_misses 0\r\n"\
|
|
47
|
-
"STAT decr_hits 0\r\nSTAT cas_misses 0\r\nSTAT cas_hits 0\r\nSTAT cas_badval 0\r\n"\
|
|
48
|
-
"STAT touch_hits 0\r\nSTAT touch_misses 0\r\nSTAT auth_cmds 0\r\nSTAT auth_errors 0\r\n"\
|
|
49
|
-
"STAT bytes_read 189356\r\nSTAT bytes_written 2906615\r\nSTAT limit_maxbytes 209715200\r\n"\
|
|
50
|
-
"STAT accepting_conns 1\r\nSTAT listen_disabled_num 0\r\nSTAT threads 1\r\n"\
|
|
51
|
-
"STAT conn_yields 0\r\nSTAT curr_config 1\r\nSTAT hash_power_level 16\r\n"\
|
|
52
|
-
"STAT hash_bytes 524288\r\nSTAT hash_is_expanding 0\r\nSTAT expired_unfetched 0\r\n"\
|
|
53
|
-
"STAT evicted_unfetched 0\r\nSTAT bytes 0\r\nSTAT curr_items 0\r\nSTAT total_items 0\r\n"\
|
|
54
|
-
"STAT evictions 0\r\nSTAT reclaimed 0\r\n"
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
it 'parses out the engine version' do
|
|
58
|
-
expect(response.engine_version).to eq engine_version
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
context "when the version number is the string 'unknown'" do
|
|
64
|
-
let(:engine_version) { 'UNKNOWN' }
|
|
65
|
-
|
|
66
|
-
context 'when the response with the version stat only includes the version number' do
|
|
67
|
-
let(:response_text) do
|
|
68
|
-
"STAT pid 1\r\nSTAT uptime 68717\r\nSTAT time 1398885375\r\n"\
|
|
69
|
-
"STAT version #{engine_version}\r\n"\
|
|
70
|
-
"STAT libevent 1.4.13-stable\r\nSTAT pointer_size 64\r\nSTAT rusage_user 0.136008\r\n"\
|
|
71
|
-
"STAT rusage_system 0.424026\r\nSTAT curr_connections 5\r\nSTAT total_connections 1159\r\n"\
|
|
72
|
-
"STAT connection_structures 6\r\nSTAT reserved_fds 5\r\nSTAT cmd_get 0\r\n"\
|
|
73
|
-
"STAT cmd_set 0\r\nSTAT cmd_flush 0\r\nSTAT cmd_touch 0\r\nSTAT cmd_config_get 4582\r\n"\
|
|
74
|
-
"STAT cmd_config_set 2\r\nSTAT get_hits 0\r\nSTAT get_misses 0\r\nSTAT delete_misses 0\r\n"\
|
|
75
|
-
"STAT delete_hits 0\r\nSTAT incr_misses 0\r\nSTAT incr_hits 0\r\nSTAT decr_misses 0\r\n"\
|
|
76
|
-
"STAT decr_hits 0\r\nSTAT cas_misses 0\r\nSTAT cas_hits 0\r\nSTAT cas_badval 0\r\n"\
|
|
77
|
-
"STAT touch_hits 0\r\nSTAT touch_misses 0\r\nSTAT auth_cmds 0\r\nSTAT auth_errors 0\r\n"\
|
|
78
|
-
"STAT bytes_read 189356\r\nSTAT bytes_written 2906615\r\nSTAT limit_maxbytes 209715200\r\n"\
|
|
79
|
-
"STAT accepting_conns 1\r\nSTAT listen_disabled_num 0\r\nSTAT threads 1\r\n"\
|
|
80
|
-
"STAT conn_yields 0\r\nSTAT curr_config 1\r\nSTAT hash_power_level 16\r\n"\
|
|
81
|
-
"STAT hash_bytes 524288\r\nSTAT hash_is_expanding 0\r\nSTAT expired_unfetched 0\r\n"\
|
|
82
|
-
"STAT evicted_unfetched 0\r\nSTAT bytes 0\r\nSTAT curr_items 0\r\nSTAT total_items 0\r\n"\
|
|
83
|
-
"STAT evictions 0\r\nSTAT reclaimed 0\r\n"
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
it "parses out the engine version as 'UNKNOWN'" do
|
|
87
|
-
expect(response.engine_version).to eq engine_version
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
context 'when the response with the version stat includes the version number and trailing text' do
|
|
92
|
-
let(:response_text) do
|
|
93
|
-
"STAT pid 1\r\nSTAT uptime 68717\r\nSTAT time 1398885375\r\n"\
|
|
94
|
-
"STAT version #{engine_version} #{SecureRandom.hex(5)}\r\n"\
|
|
95
|
-
"STAT libevent 1.4.13-stable\r\nSTAT pointer_size 64\r\nSTAT rusage_user 0.136008\r\n"\
|
|
96
|
-
"STAT rusage_system 0.424026\r\nSTAT curr_connections 5\r\nSTAT total_connections 1159\r\n"\
|
|
97
|
-
"STAT connection_structures 6\r\nSTAT reserved_fds 5\r\nSTAT cmd_get 0\r\n"\
|
|
98
|
-
"STAT cmd_set 0\r\nSTAT cmd_flush 0\r\nSTAT cmd_touch 0\r\nSTAT cmd_config_get 4582\r\n"\
|
|
99
|
-
"STAT cmd_config_set 2\r\nSTAT get_hits 0\r\nSTAT get_misses 0\r\nSTAT delete_misses 0\r\n"\
|
|
100
|
-
"STAT delete_hits 0\r\nSTAT incr_misses 0\r\nSTAT incr_hits 0\r\nSTAT decr_misses 0\r\n"\
|
|
101
|
-
"STAT decr_hits 0\r\nSTAT cas_misses 0\r\nSTAT cas_hits 0\r\nSTAT cas_badval 0\r\n"\
|
|
102
|
-
"STAT touch_hits 0\r\nSTAT touch_misses 0\r\nSTAT auth_cmds 0\r\nSTAT auth_errors 0\r\n"\
|
|
103
|
-
"STAT bytes_read 189356\r\nSTAT bytes_written 2906615\r\nSTAT limit_maxbytes 209715200\r\n"\
|
|
104
|
-
"STAT accepting_conns 1\r\nSTAT listen_disabled_num 0\r\nSTAT threads 1\r\n"\
|
|
105
|
-
"STAT conn_yields 0\r\nSTAT curr_config 1\r\nSTAT hash_power_level 16\r\n"\
|
|
106
|
-
"STAT hash_bytes 524288\r\nSTAT hash_is_expanding 0\r\nSTAT expired_unfetched 0\r\n"\
|
|
107
|
-
"STAT evicted_unfetched 0\r\nSTAT bytes 0\r\nSTAT curr_items 0\r\nSTAT total_items 0\r\n"\
|
|
108
|
-
"STAT evictions 0\r\nSTAT reclaimed 0\r\n"
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
it "parses out the engine version as 'UNKNOWN'" do
|
|
112
|
-
expect(response.engine_version).to eq engine_version
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
end
|