riak-client 2.4.0 → 2.4.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.
@@ -1,6 +1,5 @@
1
1
  module Riak
2
2
  module Crdt
3
-
4
3
  # A distributed map of multiple fields, such as counters, flags, registers,
5
4
  # sets, and, recursively, other maps, using the Riak 2 Data Types feature.
6
5
  #
@@ -1,3 +1,5 @@
1
+ require 'riak/util/string'
2
+
1
3
  module Riak
2
4
  module Crdt
3
5
 
@@ -6,6 +8,7 @@ module Riak
6
8
  # Uses the Ruby standard library `::Set` frequently, so the full class names will
7
9
  # be used frequently.
8
10
  class Set < Base
11
+ include Util::String
9
12
 
10
13
  # Create a set instance. The bucket type is determined by the first of
11
14
  # these sources:
@@ -73,7 +76,7 @@ module Riak
73
76
  # @param [String] candidate string to check for inclusion in this structure
74
77
  # @return [Boolean] if the structure includes
75
78
  def include?(candidate)
76
- members.include?(candidate)
79
+ members.any? { |m| equal_bytes?(m, candidate) }
77
80
  end
78
81
 
79
82
  # Add a {String} to the {Riak::Crdt::Set}
@@ -74,7 +74,7 @@ module Riak
74
74
  # @param [String] key the key to get the value for
75
75
  # @return the value for the given key
76
76
  def [](key)
77
- key = normalize_key key
77
+ key = normalize_key(key)
78
78
  if include? key
79
79
  candidate = @contents[key]
80
80
  return candidate unless candidate.respond_to? :parent
@@ -97,7 +97,7 @@ module Riak
97
97
  # @param [Boolean, String, Integer] value the value to set at the key,
98
98
  # or in the case of counters, the amount to increment
99
99
  def []=(key, value)
100
- key = normalize_key key
100
+ key = normalize_key(key)
101
101
 
102
102
  operation = @type.update value
103
103
  operation.name = key
@@ -112,11 +112,15 @@ module Riak
112
112
 
113
113
  alias_method :increment, :[]=
114
114
 
115
+ def length
116
+ @contents.length
117
+ end
118
+
115
119
  # Remove the entry from the map.
116
120
  #
117
121
  # @param [String] key the key to remove from the map
118
122
  def delete(key)
119
- key = normalize_key key
123
+ key = normalize_key(key)
120
124
  operation = @type.delete
121
125
  operation.name = key
122
126
 
@@ -127,7 +131,7 @@ module Riak
127
131
 
128
132
  # @api private
129
133
  def operate(key, inner_operation)
130
- key = normalize_key key
134
+ key = normalize_key(key)
131
135
 
132
136
  inner_operation.name = key
133
137
 
@@ -152,7 +156,7 @@ module Riak
152
156
  private
153
157
 
154
158
  def normalize_key(unnormalized_key)
155
- unnormalized_key.to_s
159
+ unnormalized_key.to_s.dup.force_encoding('binary')
156
160
  end
157
161
 
158
162
  def initialize_nil?
@@ -0,0 +1,31 @@
1
+ module Riak
2
+ module Util
3
+ # Methods comparing strings
4
+ module String
5
+ def equal_bytes?(a, b)
6
+ return true if a.nil? && b.nil?
7
+
8
+ return false unless a.respond_to?(:bytesize)
9
+ return false unless b.respond_to?(:bytesize)
10
+ return false unless a.bytesize == b.bytesize
11
+
12
+ return false unless a.respond_to?(:bytes)
13
+ return false unless b.respond_to?(:bytes)
14
+
15
+ b1 = a.bytes.to_a
16
+ b2 = b.bytes.to_a
17
+ i = 0
18
+ loop do
19
+ c1 = b1[i]
20
+ c2 = b2[i]
21
+ return false unless c1 == c2
22
+ i += 1
23
+ break if i > b1.length
24
+ end
25
+ true
26
+ end
27
+
28
+ module_function :equal_bytes?
29
+ end
30
+ end
31
+ end
@@ -1,3 +1,3 @@
1
1
  module Riak
2
- VERSION = "2.4.0"
2
+ VERSION = "2.4.1"
3
3
  end
@@ -15,19 +15,20 @@ Gem::Specification.new do |gem|
15
15
  gem.required_ruby_version = '>= 1.9.3'
16
16
 
17
17
  # Deps
18
- gem.add_development_dependency 'rspec', '~> 3.0'
19
- gem.add_development_dependency 'rake', '~> 10.1'
20
- gem.add_development_dependency 'yard', '~> 0.8'
18
+ gem.add_development_dependency 'activesupport', '~> 4.2'
19
+ gem.add_development_dependency 'instrumentable', '~> 1.1'
21
20
  gem.add_development_dependency 'kramdown', '~> 1.4'
21
+ gem.add_development_dependency 'rake', '~> 10.1'
22
+ gem.add_development_dependency 'rspec', '~> 3.0'
23
+ gem.add_development_dependency 'rubocop', '~> 0.40.0'
22
24
  gem.add_development_dependency 'simplecov', '~> 0.10'
23
- gem.add_development_dependency 'instrumentable', '~> 1.1'
24
- gem.add_development_dependency 'rubocop', '~> 0.40'
25
+ gem.add_development_dependency 'yard', '~> 0.8'
25
26
 
26
- gem.add_runtime_dependency 'i18n', '~> 0.6'
27
27
  gem.add_runtime_dependency 'beefcake', '~> 1.1'
28
- gem.add_runtime_dependency 'multi_json', '~> 1.0'
29
- gem.add_runtime_dependency 'innertube', '~> 1.0'
30
28
  gem.add_runtime_dependency 'cert_validator', '~> 0.0.1'
29
+ gem.add_runtime_dependency 'i18n', '~> 0.6'
30
+ gem.add_runtime_dependency 'innertube', '~> 1.0'
31
+ gem.add_runtime_dependency 'multi_json', '~> 1.0'
31
32
 
32
33
  # Files
33
34
 
@@ -1,6 +1,7 @@
1
1
  # coding: utf-8
2
2
  require 'spec_helper'
3
3
  require 'riak'
4
+ require 'riak/util/string'
4
5
 
5
6
  describe 'Encoding and CRDTs', integration: true, search_config: true do
6
7
  shared_examples 'CRDTs with weird names' do
@@ -16,6 +17,7 @@ describe 'Encoding and CRDTs', integration: true, search_config: true do
16
17
 
17
18
  it 'creates counters' do
18
19
  counter = nil
20
+
19
21
  expect{ counter = Riak::Crdt::Counter.new counter_bucket, random_string }.
20
22
  to_not raise_error
21
23
 
@@ -24,44 +26,61 @@ describe 'Encoding and CRDTs', integration: true, search_config: true do
24
26
  expect(value = counter.value).to be_a Numeric
25
27
 
26
28
  expect{ counter.increment }.to_not raise_error
29
+
27
30
  expect(counter.value).to eq value + 1
28
31
  end
29
32
 
30
33
  it 'updates registers in maps' do
31
34
  map = nil
35
+
36
+ expect(random_string.encoding.name).to eq expected_encoding
37
+
32
38
  expect{ map = Riak::Crdt::Map.new map_bucket, random_string }.
33
39
  to_not raise_error
34
40
 
35
41
  expect(map).to be_a Riak::Crdt::Map
36
42
 
37
43
  expect(map.registers[random_string]).to be_nil
44
+
38
45
  expect{ map.registers[random_string] = random_string }.
39
46
  to_not raise_error
40
47
 
41
- expect(map.registers[random_string]).to eq random_string
48
+ expect(map.registers.length).to eq 1
49
+
50
+ expect(map.registers[random_string]).to_not be_nil
51
+
52
+ expect(Riak::Util::String.equal_bytes?(map.registers[random_string], random_string)).to be
53
+
54
+ expect(random_string.encoding.name).to eq expected_encoding
42
55
  end
43
56
 
44
57
  it 'updates sets' do
45
58
  set = nil
59
+
60
+ expect(random_string.encoding.name).to eq expected_encoding
61
+
46
62
  expect{ set = Riak::Crdt::Set.new set_bucket, random_string }.
47
63
  to_not raise_error
48
64
 
49
65
  expect(set).to be_a Riak::Crdt::Set
50
66
 
51
- expect(set.members).to_not include random_string
67
+ expect(set.include?(random_string)).to_not be
52
68
 
53
69
  set.add random_string
54
70
 
55
- expect(set.members).to include random_string
71
+ expect(set.include?(random_string)).to be
56
72
 
57
73
  set.remove random_string
58
74
 
59
- expect(set.members).to_not include random_string
75
+ expect(set.include?(random_string)).to_not be
76
+
77
+ expect(random_string.encoding.name).to eq expected_encoding
60
78
  end
61
79
  end
62
80
 
63
81
  describe 'with utf-8 strings' do
64
82
  let(:string){ "\xF0\x9F\x9A\xB4こんにちはสวัสดี" }
83
+ let(:expected_encoding){ 'UTF-8' }
65
84
  let(:random_string){ string + random_key }
66
85
 
67
86
  include_examples 'CRDTs with weird names'
@@ -69,6 +88,7 @@ describe 'Encoding and CRDTs', integration: true, search_config: true do
69
88
 
70
89
  describe 'with binary strings' do
71
90
  let(:string){ "\xff\xff".force_encoding('binary') }
91
+ let(:expected_encoding){ 'ASCII-8BIT' }
72
92
  let(:random_string){ string + random_key }
73
93
 
74
94
  include_examples 'CRDTs with weird names'
@@ -5,170 +5,174 @@ require 'riak/client/beefcake/messages'
5
5
  require 'riak/client/beefcake/protocol'
6
6
 
7
7
  describe 'Protocol Buffers', test_client: true, integration: true do
8
- describe 'timeouts' do
9
- it 'raises error on connect timeout' do
10
- # unroutable TEST-NET (https://tools.ietf.org/html/rfc5737)
11
- config = {}
12
- config[:host] = '192.0.2.0'
13
- config[:pb_port] = 65535
14
-
15
- config[:connect_timeout] = 0.0001
16
- client = Riak::Client.new(config)
17
-
18
- expect do
19
- client.ping
20
- end.to raise_error RuntimeError, /timed out/
21
- end
22
-
23
- it 'raises error on read timeout' do
24
- ok_to_continue = false
25
- quitting = false
26
- port = 0
8
+ if RUBY_VERSION >= '2.0.0'
9
+ describe 'timeouts' do
10
+ it 'raises error on connect timeout' do
11
+ # unroutable TEST-NET (https://tools.ietf.org/html/rfc5737)
12
+ config = {}
13
+ config[:host] = '192.0.2.0'
14
+ config[:pb_port] = 65535
15
+
16
+ config[:connect_timeout] = 0.0001
17
+ client = Riak::Client.new(config)
18
+
19
+ expect do
20
+ client.ping
21
+ end.to raise_error RuntimeError, /timed out/
22
+ end
27
23
 
28
- server = nil
29
- thr = Thread.new do
30
- server = TCPServer.new port
31
- port = server.addr[1]
32
- ok_to_continue = true
33
- loop do
34
- begin
35
- Thread.start(server.accept) do |s|
36
- loop do
37
- p = Riak::Client::BeefcakeProtobuffsBackend::Protocol.new s
38
- begin
39
- msgname, _body = p.receive
40
- rescue IOError
41
- break if quitting
42
- raise
43
- end
44
- case msgname
45
- when :PingReq
46
- sleep 0.5
47
- p.write :PingResp
48
- else
49
- $stderr.puts("unknown msgname: #{msgname}")
24
+ it 'raises error on read timeout' do
25
+ ok_to_continue = false
26
+ quitting = false
27
+ port = 0
28
+
29
+ server = nil
30
+ thr = Thread.new do
31
+ server = TCPServer.new port
32
+ port = server.addr[1]
33
+ ok_to_continue = true
34
+ loop do
35
+ begin
36
+ Thread.start(server.accept) do |s|
37
+ loop do
38
+ p = Riak::Client::BeefcakeProtobuffsBackend::Protocol.new s
39
+ begin
40
+ msgname, _body = p.receive
41
+ rescue IOError
42
+ break if quitting
43
+ raise
44
+ end
45
+ case msgname
46
+ when :PingReq
47
+ sleep 0.5
48
+ p.write :PingResp
49
+ else
50
+ $stderr.puts("unknown msgname: #{msgname}")
51
+ end
50
52
  end
51
53
  end
54
+ rescue IOError
55
+ break if quitting
56
+ raise
52
57
  end
53
- rescue IOError
54
- break if quitting
55
- raise
56
58
  end
57
59
  end
58
- end
59
60
 
60
- loop do
61
- break if ok_to_continue
62
- sleep 0.1
63
- end
64
- ok_to_continue = false
65
-
66
- config = {}
67
- config[:pb_port] = port
68
- config[:client_id] = port
69
- config[:read_timeout] = 0.0001
70
- client = Riak::Client.new(config)
71
-
72
- max_ping_attempts = 16
73
- ping_count = 0
74
- loop do
75
- begin
76
- client.ping
77
- ping_count += 1
78
- break if ping_count > max_ping_attempts
79
- rescue RuntimeError => e
80
- break if e.message =~ /timed out/
61
+ loop do
62
+ break if ok_to_continue
63
+ sleep 0.1
81
64
  end
82
- sleep 0.5
83
- end
84
-
85
- quitting = true
86
- server.close
87
- thr.join
65
+ ok_to_continue = false
88
66
 
89
- expect(ping_count).to be < max_ping_attempts
90
- end
91
-
92
- it 'raises error on write timeout' do
93
- ok_to_continue = false
94
- quitting = false
95
- port = 0
67
+ config = {}
68
+ config[:pb_port] = port
69
+ config[:client_id] = port
70
+ config[:read_timeout] = 0.0001
71
+ client = Riak::Client.new(config)
96
72
 
97
- server = nil
98
- thr = Thread.new do
99
- server = TCPServer.new port
100
- port = server.addr[1]
101
- ok_to_continue = true
73
+ max_ping_attempts = 16
74
+ ping_count = 0
102
75
  loop do
103
76
  begin
104
- Thread.start(server.accept) do |s|
105
- loop do
106
- p = Riak::Client::BeefcakeProtobuffsBackend::Protocol.new s
107
- begin
108
- msgname, _body = p.receive
109
- rescue IOError
110
- break if quitting
111
- raise
112
- end
113
- case msgname
114
- when :PingReq
115
- p.write :PingResp
116
- when :GetServerInfoReq
117
- r = Riak::Client::BeefcakeProtobuffsBackend::RpbGetServerInfoResp.new
118
- r.node = 'dev1@127.0.0.1'.force_encoding('BINARY')
119
- r.server_version = '2.1.4'.force_encoding('BINARY')
120
- p.write :GetServerInfoResp, r
121
- when :PutReq
122
- r = Riak::Client::BeefcakeProtobuffsBackend::RpbPutResp.new
123
- p.write :PutResp, r
124
- else
125
- $stderr.puts("unknown msgname: #{msgname}")
77
+ client.ping
78
+ ping_count += 1
79
+ break if ping_count > max_ping_attempts
80
+ rescue RuntimeError => e
81
+ break if e.message =~ /timed out/
82
+ end
83
+ sleep 0.5
84
+ end
85
+
86
+ quitting = true
87
+ server.close
88
+ thr.join
89
+
90
+ expect(ping_count).to be < max_ping_attempts
91
+ end
92
+
93
+ it 'raises error on write timeout' do
94
+ ok_to_continue = false
95
+ quitting = false
96
+ port = 0
97
+
98
+ server = nil
99
+ thr = Thread.new do
100
+ server = TCPServer.new port
101
+ port = server.addr[1]
102
+ ok_to_continue = true
103
+ loop do
104
+ begin
105
+ Thread.start(server.accept) do |s|
106
+ loop do
107
+ p = Riak::Client::BeefcakeProtobuffsBackend::Protocol.new s
108
+ begin
109
+ msgname, _body = p.receive
110
+ rescue IOError
111
+ break if quitting
112
+ raise
113
+ end
114
+ case msgname
115
+ when :PingReq
116
+ p.write :PingResp
117
+ when :GetServerInfoReq
118
+ r = Riak::Client::BeefcakeProtobuffsBackend::RpbGetServerInfoResp.new
119
+ r.node = 'dev1@127.0.0.1'.force_encoding('BINARY')
120
+ r.server_version = '2.1.4'.force_encoding('BINARY')
121
+ p.write :GetServerInfoResp, r
122
+ when :PutReq
123
+ r = Riak::Client::BeefcakeProtobuffsBackend::RpbPutResp.new
124
+ p.write :PutResp, r
125
+ else
126
+ $stderr.puts("unknown msgname: #{msgname}")
127
+ end
126
128
  end
127
129
  end
130
+ rescue IOError
131
+ break if quitting
132
+ raise
128
133
  end
129
- rescue IOError
130
- break if quitting
131
- raise
132
134
  end
133
135
  end
134
- end
135
136
 
136
- loop do
137
- break if ok_to_continue
138
- sleep 0.1
139
- end
140
- ok_to_continue = false
141
-
142
- config = {}
143
- config[:pb_port] = port
144
- config[:client_id] = port
145
- config[:write_timeout] = 0.0001
146
- client = Riak::Client.new(config)
147
-
148
- bucket = client.bucket('timeouts')
149
-
150
- max_store_attempts = 16
151
- store_count = 0
152
- loop do
153
- begin
154
- obj = bucket.new "obj-#{store_count}"
155
- # write enough data to grow beyond socket buffer capacity
156
- obj.data = SecureRandom.urlsafe_base64(10_000_000)
157
- obj.content_type = 'text/plain'
158
- obj.store
159
- store_count += 1
160
- break if store_count > max_store_attempts
161
- rescue RuntimeError => e
162
- break if e.message =~ /timed out/
137
+ loop do
138
+ break if ok_to_continue
139
+ sleep 0.1
163
140
  end
164
- sleep 0.5
165
- end
141
+ ok_to_continue = false
166
142
 
167
- quitting = true
168
- server.close
169
- thr.join
143
+ config = {}
144
+ config[:pb_port] = port
145
+ config[:client_id] = port
146
+ config[:write_timeout] = 0.0001
147
+ client = Riak::Client.new(config)
170
148
 
171
- expect(store_count).to be < max_store_attempts
149
+ bucket = client.bucket('timeouts')
150
+
151
+ max_store_attempts = 16
152
+ store_count = 0
153
+ loop do
154
+ begin
155
+ obj = bucket.new "obj-#{store_count}"
156
+ # write enough data to grow beyond socket buffer capacity
157
+ obj.data = SecureRandom.urlsafe_base64(10_000_000)
158
+ obj.content_type = 'text/plain'
159
+ obj.store
160
+ store_count += 1
161
+ break if store_count > max_store_attempts
162
+ rescue RuntimeError => e
163
+ break if e.message =~ /timed out/
164
+ end
165
+ sleep 0.5
166
+ end
167
+
168
+ quitting = true
169
+ server.close
170
+ thr.join
171
+
172
+ expect(store_count).to be < max_store_attempts
173
+ end
172
174
  end
175
+ else
176
+ skip 'not supported in this version of Ruby'
173
177
  end
174
178
  end