riak-client 1.4.5 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/Gemfile +0 -1
  4. data/{LICENSE → LICENSE.md} +0 -0
  5. data/README.markdown +211 -66
  6. data/RELEASE_NOTES.md +22 -47
  7. data/Rakefile +45 -0
  8. data/lib/riak.rb +1 -1
  9. data/lib/riak/bucket.rb +2 -2
  10. data/lib/riak/client.rb +22 -195
  11. data/lib/riak/client/beefcake/crdt_loader.rb +127 -0
  12. data/lib/riak/client/beefcake/crdt_operator.rb +222 -0
  13. data/lib/riak/client/beefcake/footer +4 -0
  14. data/lib/riak/client/beefcake/header +6 -0
  15. data/lib/riak/client/beefcake/message_codes.rb +29 -0
  16. data/lib/riak/client/beefcake/message_overlay.rb +61 -0
  17. data/lib/riak/client/beefcake/messages.rb +733 -371
  18. data/lib/riak/client/beefcake/object_methods.rb +1 -1
  19. data/lib/riak/client/beefcake/protocol.rb +105 -0
  20. data/lib/riak/client/beefcake/socket.rb +243 -0
  21. data/lib/riak/client/beefcake_protobuffs_backend.rb +262 -122
  22. data/lib/riak/client/node.rb +4 -75
  23. data/lib/riak/client/protobuffs_backend.rb +6 -14
  24. data/lib/riak/client/search.rb +0 -64
  25. data/lib/riak/client/yokozuna.rb +52 -0
  26. data/lib/riak/counter.rb +1 -1
  27. data/lib/riak/crdt.rb +21 -0
  28. data/lib/riak/crdt/base.rb +97 -0
  29. data/lib/riak/crdt/batch_counter.rb +19 -0
  30. data/lib/riak/crdt/batch_map.rb +41 -0
  31. data/lib/riak/crdt/counter.rb +71 -0
  32. data/lib/riak/crdt/inner_counter.rb +74 -0
  33. data/lib/riak/crdt/inner_flag.rb +42 -0
  34. data/lib/riak/crdt/inner_map.rb +53 -0
  35. data/lib/riak/crdt/inner_register.rb +26 -0
  36. data/lib/riak/crdt/inner_set.rb +95 -0
  37. data/lib/riak/crdt/map.rb +88 -0
  38. data/lib/riak/crdt/operation.rb +19 -0
  39. data/lib/riak/crdt/set.rb +156 -0
  40. data/lib/riak/crdt/typed_collection.rb +131 -0
  41. data/lib/riak/errors/base.rb +9 -0
  42. data/lib/riak/errors/connection_error.rb +44 -0
  43. data/lib/riak/errors/crdt_error.rb +18 -0
  44. data/lib/riak/errors/failed_request.rb +56 -0
  45. data/lib/riak/errors/protobuffs_error.rb +11 -0
  46. data/lib/riak/i18n.rb +2 -0
  47. data/lib/riak/json.rb +1 -1
  48. data/lib/riak/locale/en.yml +26 -1
  49. data/lib/riak/locale/fr.yml +0 -1
  50. data/lib/riak/map_reduce.rb +1 -1
  51. data/lib/riak/map_reduce/results.rb +1 -1
  52. data/lib/riak/multiget.rb +1 -2
  53. data/lib/riak/rcontent.rb +8 -3
  54. data/lib/riak/robject.rb +2 -8
  55. data/lib/riak/secondary_index.rb +4 -4
  56. data/lib/riak/serializers.rb +1 -1
  57. data/lib/riak/util/escape.rb +3 -5
  58. data/lib/riak/version.rb +1 -1
  59. data/lib/riak/walk_spec.rb +7 -3
  60. data/riak-client.gemspec +10 -8
  61. data/spec/fixtures/bitcask.txt +25 -0
  62. data/spec/integration/riak/bucket_types_spec.rb +61 -0
  63. data/spec/integration/riak/counters_spec.rb +17 -32
  64. data/spec/integration/riak/crdt_spec.rb +181 -0
  65. data/spec/integration/riak/crdt_validation/map_spec.rb +63 -0
  66. data/spec/integration/riak/crdt_validation/set_spec.rb +122 -0
  67. data/spec/integration/riak/protobuffs_backends_spec.rb +9 -26
  68. data/spec/integration/riak/security_spec.rb +94 -0
  69. data/spec/integration/riak/threading_spec.rb +24 -67
  70. data/spec/integration/yokozuna/index_spec.rb +61 -0
  71. data/spec/integration/yokozuna/queries_spec.rb +116 -0
  72. data/spec/integration/yokozuna/schema_spec.rb +49 -0
  73. data/spec/riak/beefcake_protobuffs_backend/crdt_operator_spec.rb +222 -0
  74. data/spec/riak/beefcake_protobuffs_backend/object_methods_spec.rb +4 -4
  75. data/spec/riak/beefcake_protobuffs_backend/protocol_spec.rb +189 -0
  76. data/spec/riak/beefcake_protobuffs_backend/socket_spec.rb +151 -0
  77. data/spec/riak/beefcake_protobuffs_backend_spec.rb +68 -106
  78. data/spec/riak/bucket_spec.rb +81 -77
  79. data/spec/riak/client_spec.rb +43 -340
  80. data/spec/riak/core_ext/to_param_spec.rb +2 -2
  81. data/spec/riak/counter_spec.rb +20 -20
  82. data/spec/riak/crdt/counter_spec.rb +52 -0
  83. data/spec/riak/crdt/inner_counter_spec.rb +21 -0
  84. data/spec/riak/crdt/inner_flag_spec.rb +39 -0
  85. data/spec/riak/crdt/inner_map_spec.rb +47 -0
  86. data/spec/riak/crdt/inner_register_spec.rb +40 -0
  87. data/spec/riak/crdt/inner_set_spec.rb +33 -0
  88. data/spec/riak/crdt/map_spec.rb +77 -0
  89. data/spec/riak/crdt/set_spec.rb +58 -0
  90. data/spec/riak/crdt/shared_examples.rb +74 -0
  91. data/spec/riak/crdt/typed_collection_spec.rb +231 -0
  92. data/spec/riak/escape_spec.rb +33 -37
  93. data/spec/riak/feature_detection_spec.rb +45 -45
  94. data/spec/riak/index_collection_spec.rb +12 -12
  95. data/spec/riak/link_spec.rb +34 -34
  96. data/spec/riak/list_buckets_spec.rb +7 -7
  97. data/spec/riak/map_reduce/filter_builder_spec.rb +6 -6
  98. data/spec/riak/map_reduce/phase_spec.rb +35 -35
  99. data/spec/riak/map_reduce_spec.rb +89 -87
  100. data/spec/riak/multiget_spec.rb +20 -15
  101. data/spec/riak/node_spec.rb +5 -152
  102. data/spec/riak/robject_spec.rb +95 -108
  103. data/spec/riak/search_spec.rb +17 -139
  104. data/spec/riak/secondary_index_spec.rb +49 -49
  105. data/spec/riak/serializers_spec.rb +9 -9
  106. data/spec/riak/stamp_spec.rb +9 -9
  107. data/spec/riak/walk_spec_spec.rb +46 -46
  108. data/spec/spec_helper.rb +14 -22
  109. data/spec/support/certs/README.md +13 -0
  110. data/spec/support/certs/ca.crt +22 -0
  111. data/spec/support/certs/client.crt +95 -0
  112. data/spec/support/certs/client.key +27 -0
  113. data/spec/support/certs/empty_ca.crt +21 -0
  114. data/spec/support/certs/server.crl +13 -0
  115. data/spec/support/certs/server.crt +95 -0
  116. data/spec/support/certs/server.key +27 -0
  117. data/spec/support/integration_setup.rb +1 -1
  118. data/spec/support/search_corpus_setup.rb +29 -8
  119. data/spec/support/test_client.rb +46 -0
  120. data/spec/support/test_client.yml.example +10 -0
  121. data/spec/support/unified_backend_examples.rb +104 -83
  122. data/spec/support/version_filter.rb +2 -2
  123. data/spec/support/wait_until.rb +14 -0
  124. metadata +134 -132
  125. data/erl_src/riak_kv_test014_backend.beam +0 -0
  126. data/erl_src/riak_kv_test014_backend.erl +0 -189
  127. data/erl_src/riak_kv_test_backend.beam +0 -0
  128. data/erl_src/riak_kv_test_backend.erl +0 -731
  129. data/erl_src/riak_search_test_backend.beam +0 -0
  130. data/erl_src/riak_search_test_backend.erl +0 -175
  131. data/lib/riak/client/excon_backend.rb +0 -172
  132. data/lib/riak/client/http_backend.rb +0 -413
  133. data/lib/riak/client/http_backend/bucket_streamer.rb +0 -15
  134. data/lib/riak/client/http_backend/chunked_json_streamer.rb +0 -42
  135. data/lib/riak/client/http_backend/configuration.rb +0 -227
  136. data/lib/riak/client/http_backend/key_streamer.rb +0 -15
  137. data/lib/riak/client/http_backend/object_methods.rb +0 -114
  138. data/lib/riak/client/http_backend/request_headers.rb +0 -34
  139. data/lib/riak/client/http_backend/transport_methods.rb +0 -201
  140. data/lib/riak/client/instrumentation.rb +0 -25
  141. data/lib/riak/client/net_http_backend.rb +0 -82
  142. data/lib/riak/cluster.rb +0 -151
  143. data/lib/riak/failed_request.rb +0 -81
  144. data/lib/riak/instrumentation.rb +0 -6
  145. data/lib/riak/node.rb +0 -40
  146. data/lib/riak/node/configuration.rb +0 -304
  147. data/lib/riak/node/console.rb +0 -133
  148. data/lib/riak/node/control.rb +0 -207
  149. data/lib/riak/node/defaults.rb +0 -85
  150. data/lib/riak/node/generation.rb +0 -127
  151. data/lib/riak/node/log.rb +0 -34
  152. data/lib/riak/node/version.rb +0 -29
  153. data/lib/riak/search.rb +0 -3
  154. data/lib/riak/test_server.rb +0 -89
  155. data/lib/riak/util/headers.rb +0 -32
  156. data/lib/riak/util/multipart.rb +0 -52
  157. data/lib/riak/util/multipart/stream_parser.rb +0 -62
  158. data/spec/fixtures/munchausen.txt +0 -1033
  159. data/spec/integration/riak/cluster_spec.rb +0 -88
  160. data/spec/integration/riak/http_backends_spec.rb +0 -180
  161. data/spec/integration/riak/node_spec.rb +0 -170
  162. data/spec/integration/riak/test_server_spec.rb +0 -57
  163. data/spec/riak/excon_backend_spec.rb +0 -102
  164. data/spec/riak/headers_spec.rb +0 -21
  165. data/spec/riak/http_backend/configuration_spec.rb +0 -273
  166. data/spec/riak/http_backend/object_methods_spec.rb +0 -243
  167. data/spec/riak/http_backend/transport_methods_spec.rb +0 -97
  168. data/spec/riak/http_backend_spec.rb +0 -367
  169. data/spec/riak/instrumentation_spec.rb +0 -167
  170. data/spec/riak/multipart_spec.rb +0 -23
  171. data/spec/riak/net_http_backend_spec.rb +0 -15
  172. data/spec/riak/stream_parser_spec.rb +0 -53
  173. data/spec/support/drb_mock_server.rb +0 -39
  174. data/spec/support/http_backend_implementation_examples.rb +0 -253
  175. data/spec/support/mock_server.rb +0 -81
  176. data/spec/support/mocks.rb +0 -4
  177. data/spec/support/riak_test.rb +0 -77
  178. data/spec/support/sometimes.rb +0 -46
  179. data/spec/support/test_server.rb +0 -61
  180. data/spec/support/test_server.yml.example +0 -14
@@ -12,11 +12,11 @@ describe Riak::Client::BeefcakeProtobuffsBackend::ObjectMethods do
12
12
 
13
13
  describe "loading object data from the response" do
14
14
  it "should load the key" do
15
- content = stub(:value => '', :vtag => nil, :content_type => nil, :links => nil, :usermeta => nil, :last_mod => nil, :indexes => nil, :charset => nil)
16
- pbuf = stub(:vclock => nil, :content => [content], :value => nil, :key => 'akey')
15
+ content = double(:value => '', :vtag => nil, :content_type => nil, :links => nil, :usermeta => nil, :last_mod => nil, :indexes => nil, :charset => nil)
16
+ pbuf = double(:vclock => nil, :content => [content], :value => nil, :key => 'akey')
17
17
  o = @backend.load_object(pbuf, @object)
18
- o.should == @object
19
- o.key.should == pbuf.key
18
+ expect(o).to eq(@object)
19
+ expect(o.key).to eq(pbuf.key)
20
20
  end
21
21
  end
22
22
 
@@ -0,0 +1,189 @@
1
+ require 'spec_helper'
2
+ require 'riak/client/beefcake/protocol'
3
+
4
+ describe Riak::Client::BeefcakeProtobuffsBackend::Protocol do
5
+ let(:socket){ double 'Socket' }
6
+ subject{ described_class.new socket }
7
+ let(:codes){ Riak::Client::BeefcakeMessageCodes }
8
+
9
+ let(:yz_req){ Riak::Client::BeefcakeProtobuffsBackend::
10
+ RpbYokozunaSchemaGetReq.new name: 'schema' }
11
+ let(:ctr_resp){ Riak::Client::BeefcakeProtobuffsBackend::
12
+ RpbCounterGetResp.new value: rand(2**10) }
13
+ let(:error_resp){ Riak::Client::BeefcakeProtobuffsBackend::
14
+ RpbErrorResp.new errcode: rand(2**10), errmsg: 'message' }
15
+
16
+ describe 'writing messages' do
17
+ # I really wanted to call this "send" but Ruby already has that method
18
+
19
+ it 'writes messages without a body' do
20
+ name = :PingReq
21
+
22
+ expect(socket).to receive(:write) { |payload|
23
+ length, code = payload.unpack 'NC'
24
+ expect(length).to eq 1
25
+ expect(code).to eq codes.index name
26
+ }.ordered
27
+ expect(socket).to receive(:flush).ordered
28
+
29
+ subject.write name
30
+ end
31
+
32
+ it 'writes messages with Beefcake::Message instances as bodies' do
33
+ message = yz_req
34
+ name = :YokozunaSchemaGetReq
35
+
36
+ expect(socket).to receive(:write) { |payload|
37
+ header = payload[0..4]
38
+ body = payload[5..-1]
39
+ length, code = header.unpack 'NC'
40
+ expect(code).to eq codes.index name
41
+ expect(length).to eq(body.length + 1)
42
+ expect(body).to eq message.encode.to_s
43
+ }.ordered
44
+ expect(socket).to receive(:flush).ordered
45
+
46
+ subject.write name, message
47
+ end
48
+
49
+ it 'raises an error and writes nothing when passed the wrong thing' do
50
+ expect{ subject.write :YokozunaSchemaGetReq, Object.new }.
51
+ to raise_error
52
+ end
53
+ end
54
+
55
+ describe 'receiving messages' do
56
+ it 'receives messages without a body and returns an array of code-symbol and nil' do
57
+ name = :PingResp
58
+ header = [1, codes.index(name)].pack 'NC'
59
+ expect(socket).to receive(:read).
60
+ ordered.
61
+ with(5).
62
+ and_return(header)
63
+
64
+ code, payload = subject.receive
65
+
66
+ expect(code).to eq name
67
+ expect(payload).to eq nil
68
+ end
69
+
70
+ it 'receives messages and returns an array of code-symbol and string' do
71
+ message = ctr_resp
72
+ message_str = message.encode.to_s
73
+ message_len = message_str.length
74
+ name = :CounterGetResp
75
+ header = [message_len + 1, codes.index(name)].pack 'NC'
76
+
77
+ expect(socket).to receive(:read).
78
+ ordered.
79
+ with(5).
80
+ and_return(header)
81
+ expect(socket).to receive(:read).
82
+ ordered.
83
+ with(message_len).
84
+ and_return(message_str)
85
+
86
+ code, payload = subject.receive
87
+
88
+ expect(code).to eq name
89
+ expect(payload).to eq message_str
90
+ end
91
+ end
92
+
93
+ describe 'expecting messages' do
94
+ describe 'expected message received' do
95
+ it 'accepts expected messages without a body and returns true' do
96
+ name = :PingResp
97
+ header = [1, codes.index(name)].pack 'NC'
98
+
99
+ expect(socket).to receive(:read).
100
+ with(5).
101
+ and_return(header)
102
+
103
+ payload = subject.expect name
104
+
105
+ expect(payload).to eq true
106
+ end
107
+
108
+ it 'accepts expected messages and returns a Beefcake::Message instance' do
109
+ message = ctr_resp
110
+ message_str = message.encode.to_s
111
+ message_len = message_str.length
112
+ name = :CounterGetResp
113
+ header = [message_len + 1, codes.index(name)].pack 'NC'
114
+
115
+ expect(socket).to receive(:read).
116
+ ordered.
117
+ with(5).
118
+ and_return(header)
119
+ expect(socket).to receive(:read).
120
+ ordered.
121
+ with(message_len).
122
+ and_return(message_str)
123
+
124
+ payload = subject.expect name, message.class
125
+
126
+ expect(payload).to eq message
127
+ expect(payload.value).to eq message.value
128
+ end
129
+
130
+ it 'accepts messages with an empty body when required to' do
131
+ name = :PutResp
132
+ header = [1, codes.index(name)].pack 'NC'
133
+ decoder_class = double 'RpbPutResp'
134
+
135
+ expect(socket).to receive(:read).
136
+ with(5).
137
+ and_return(header)
138
+
139
+ payload = subject.expect name, decoder_class, empty_body_acceptable: true
140
+
141
+ expect(payload).to eq :empty
142
+ end
143
+ end
144
+
145
+ describe 'unexpected message received' do
146
+ it 'raises a ProtobuffsUnexpectedResponse error' do
147
+ message = ctr_resp
148
+ message_str = message.encode.to_s
149
+ message_len = message_str.length
150
+ name = :CounterGetResp
151
+ header = [message_len + 1, codes.index(name)].pack 'NC'
152
+
153
+ expect(socket).to receive(:read).
154
+ ordered.
155
+ with(5).
156
+ and_return(header)
157
+ expect(socket).to receive(:read).
158
+ ordered.
159
+ with(message_len).
160
+ and_return(message_str)
161
+
162
+ expect{ subject.expect :PingResp }.
163
+ to raise_error Riak::ProtobuffsUnexpectedResponse
164
+ end
165
+ end
166
+
167
+ describe 'ErrorResp received' do
168
+ it 'raises a ProtobuffsErrorResponse error' do
169
+ message = error_resp
170
+ message_str = message.encode.to_s
171
+ message_len = message_str.length
172
+ name = :ErrorResp
173
+ header = [message_len + 1, codes.index(name)].pack 'NC'
174
+
175
+ expect(socket).to receive(:read).
176
+ ordered.
177
+ with(5).
178
+ and_return(header)
179
+ expect(socket).to receive(:read).
180
+ ordered.
181
+ with(message_len).
182
+ and_return(message_str)
183
+
184
+ expect{ subject.expect :PingResp }.
185
+ to raise_error Riak::ProtobuffsErrorResponse
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,151 @@
1
+ require 'spec_helper'
2
+ require 'riak/client/beefcake/socket'
3
+
4
+ describe Riak::Client::BeefcakeProtobuffsBackend::BeefcakeSocket do
5
+ let(:host){ 'host' }
6
+ let(:pb_port){ 8087 }
7
+ let(:tcp_socket_instance){ double 'TCPSocket' }
8
+
9
+ let(:ssl){ OpenSSL::SSL }
10
+
11
+ describe 'without authentication configured' do
12
+ let(:options){ Hash.new }
13
+ it 'should start a tcp connection and not start a tls connection' do
14
+ expect(TCPSocket).to receive(:new).
15
+ with(host, pb_port).
16
+ and_return(tcp_socket_instance)
17
+
18
+ expect(tcp_socket_instance).to receive(:setsockopt).
19
+ with(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)
20
+
21
+ expect(ssl::SSLSocket).not_to receive(:new)
22
+
23
+ described_class.new host, pb_port
24
+ end
25
+ end
26
+
27
+ describe 'with authentication configured' do
28
+ let(:user){ 'user' }
29
+ let(:password){ 'password' }
30
+ let(:options) do
31
+ {
32
+ authentication: {
33
+ user: user,
34
+ password: password
35
+ }
36
+ }
37
+ end
38
+ let(:ssl_socket_instance){ double 'SSLSocket' }
39
+ let(:ssl_peer_cert){ double 'Peer Certificate' }
40
+ let(:r509_cert){ double 'R509::Cert' }
41
+ let(:rcv_instance){ double 'R509::Cert::Validator instance' }
42
+
43
+ it 'should start a tcp and a tls connection, and send authentication info' do
44
+ expect(TCPSocket).to receive(:new).
45
+ with(host, pb_port).
46
+ and_return(tcp_socket_instance)
47
+
48
+ expect(tcp_socket_instance).to receive(:setsockopt).
49
+ with(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)
50
+
51
+ allow(tcp_socket_instance).to receive(:write)
52
+
53
+ # StartTls
54
+ expect(tcp_socket_instance).to receive(:read).
55
+ with(5).
56
+ and_return([1, 255].pack 'NC')
57
+
58
+ expect(ssl::SSLSocket).to receive(:new).
59
+ with(tcp_socket_instance, kind_of(OpenSSL::SSL::SSLContext)).
60
+ and_return(ssl_socket_instance)
61
+
62
+ expect(ssl_socket_instance).to receive(:connect)
63
+
64
+ allow(ssl_socket_instance).to receive(:write)
65
+
66
+ expect(ssl_socket_instance).to receive(:peer_cert).
67
+ and_return(ssl_peer_cert)
68
+ expect(R509::Cert).to receive(:new).
69
+ with(cert: ssl_peer_cert).
70
+ and_return(r509_cert)
71
+ allow(r509_cert).to receive(:valid?).and_return(true)
72
+ expect(R509::Cert::Validator).to receive(:new).
73
+ with(r509_cert).
74
+ and_return(rcv_instance)
75
+
76
+ expect(rcv_instance).to receive(:validate).
77
+ with(ocsp: false, crl: false, crl_file: nil).
78
+ and_return(true)
79
+
80
+ # AuthResp
81
+ expect(ssl_socket_instance).to receive(:read).
82
+ with(5).
83
+ and_return([1, 254].pack 'NC')
84
+
85
+ # PingResp
86
+ expect(ssl_socket_instance).to receive(:read).
87
+ with(5).
88
+ and_return([1, 2].pack 'NC')
89
+
90
+ described_class.new host, pb_port, options
91
+ end
92
+
93
+ it 'should pass pass TLS options through to OpenSSL' do
94
+ options[:authentication][:ca_file] = 'spec/support/certs/ca.crt'
95
+ options[:authentication][:key] = 'spec/support/certs/client.key'
96
+
97
+ expect(TCPSocket).to receive(:new).
98
+ with(host, pb_port).
99
+ and_return(tcp_socket_instance)
100
+
101
+ expect(tcp_socket_instance).to receive(:setsockopt).
102
+ with(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)
103
+
104
+ allow(tcp_socket_instance).to receive(:write)
105
+
106
+ # StartTls
107
+ expect(tcp_socket_instance).to receive(:read).
108
+ with(5).
109
+ and_return([1, 255].pack 'NC')
110
+
111
+ expect(ssl::SSLSocket).to receive(:new) do |sock, ctx|
112
+ expect(sock).to eq tcp_socket_instance
113
+ expect(ctx).to be_a OpenSSL::SSL::SSLContext
114
+ expect(ctx.key).to be_a OpenSSL::PKey::PKey
115
+ expect(ctx.ca_file).to eq 'spec/support/certs/ca.crt'
116
+
117
+ ssl_socket_instance
118
+ end
119
+
120
+ expect(ssl_socket_instance).to receive(:connect)
121
+
122
+ allow(ssl_socket_instance).to receive(:write)
123
+
124
+ expect(ssl_socket_instance).to receive(:peer_cert).
125
+ and_return(ssl_peer_cert)
126
+ expect(R509::Cert).to receive(:new).
127
+ with(cert: ssl_peer_cert).
128
+ and_return(r509_cert)
129
+ allow(r509_cert).to receive(:valid?).and_return(true)
130
+ expect(R509::Cert::Validator).to receive(:new).
131
+ with(r509_cert).
132
+ and_return(rcv_instance)
133
+
134
+ expect(rcv_instance).to receive(:validate).
135
+ with(ocsp: false, crl: false, crl_file: nil).
136
+ and_return(true)
137
+
138
+ # AuthResp
139
+ expect(ssl_socket_instance).to receive(:read).
140
+ with(5).
141
+ and_return([1, 254].pack 'NC')
142
+
143
+ # PingResp
144
+ expect(ssl_socket_instance).to receive(:read).
145
+ with(5).
146
+ and_return([1, 2].pack 'NC')
147
+
148
+ described_class.new host, pb_port, options
149
+ end
150
+ end
151
+ end
@@ -1,72 +1,46 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Riak::Client::BeefcakeProtobuffsBackend do
4
- before(:all) { described_class.should be_configured }
5
- before(:each) { backend.stub(:get_server_version => "1.2.0") }
4
+ before(:all) { expect(described_class).to be_configured }
6
5
  let(:client) { Riak::Client.new }
7
6
  let(:node) { client.nodes.first }
8
7
  let(:backend) { Riak::Client::BeefcakeProtobuffsBackend.new(client, node) }
9
-
10
- it "should only write to the socket one time per request" do
11
- exp_bucket, exp_keys = 'foo', ['bar']
12
- mock_socket = mock("mock TCP socket")
13
-
14
- backend.stub!(:socket).and_return(mock_socket)
15
- mock_socket.should_receive(:write).exactly(1).with do |param|
16
- len, code = param[0,5].unpack("NC")
17
- req = Riak::Client::BeefcakeProtobuffsBackend::RpbListKeysReq.decode(param[5..-1])
18
- code == 17 && req.bucket == exp_bucket
19
- end
20
-
21
- responses = Array.new(2) do |index|
22
- resp = Riak::Client::BeefcakeProtobuffsBackend::RpbListKeysResp.new
23
- if index == 0
24
- resp.keys = exp_keys
25
- else
26
- resp.done = true
27
- end
28
- resp
29
- end
30
-
31
- responses.each do |response|
32
- encoded_response = response.encode
33
- mock_socket.should_receive(:read).exactly(1).with(5).and_return([1 + encoded_response.length, 18].pack("NC"))
34
- mock_socket.should_receive(:read).exactly(1).with(encoded_response.length).and_return(encoded_response)
35
- end
36
-
37
- backend.list_keys(exp_bucket).should == exp_keys
8
+ let(:protocol){ double 'protocol' }
9
+ before(:each) do
10
+ allow(backend).to receive(:get_server_version).and_return("2.0.0")
11
+ allow(backend).to receive(:protocol).and_yield(protocol)
38
12
  end
39
13
 
40
14
  context "secondary index" do
41
15
  before :each do
42
- @socket = mock(:socket).as_null_object
43
- TCPSocket.stub(:new => @socket)
16
+ @socket = double(:socket).as_null_object
17
+ allow(TCPSocket).to receive(:new).and_return(@socket)
44
18
  end
45
19
 
46
20
  it 'should raise an appropriate error when 2i is not available' do
47
- backend.should_receive(:write_protobuff)
48
- response_message = Riak::Client::BeefcakeProtobuffsBackend::
49
- RpbErrorResp.
50
- new(errmsg: '{error,{indexes_not_supported,riak_kv_bitcask_backend}}',
51
- errcode: 0).
52
- encode
53
-
54
- response_header = [response_message.length + 1, 0].pack('NC')
55
-
56
- @socket.should_receive(:read).with(5).and_return response_header
57
- @socket.should_receive(:read).with(response_message.length).and_return response_message
58
-
59
- expect{ backend.get_index 'bucket', 'words', 'asdf' }.to raise_error "Expected success from Riak but received 0. Secondary indexes aren't supported on the riak_kv_bitcask_backend backend."
21
+ expect(protocol).to receive(:write)
22
+ expect(protocol).to receive(:expect).
23
+ and_raise(
24
+ Riak::ProtobuffsErrorResponse.
25
+ new(Riak::Client::BeefcakeProtobuffsBackend::
26
+ RpbErrorResp.
27
+ new(errmsg: '{error,{indexes_not_supported,riak_kv_bitcask_backend}}',
28
+ errcode: 0)
29
+ )
30
+ )
31
+
32
+ expect{ backend.get_index 'bucket', 'words', 'asdf' }.to raise_error /Secondary indexes aren't supported/
60
33
  # '
61
34
  end
62
35
 
63
36
  context 'when streaming' do
64
37
  it "should stream when a block is given" do
65
- backend.should_receive(:write_protobuff) do |msg, req|
66
- msg.should == :IndexReq
67
- req[:stream].should == true
38
+ expect(protocol).to receive(:write) do |msg, req|
39
+ expect(msg).to eq(:IndexReq)
40
+ expect(req[:stream]).to eq(true)
68
41
  end
69
- backend.should_receive(:decode_index_response)
42
+ expect(protocol).to receive(:expect).
43
+ and_return(Riak::Client::BeefcakeProtobuffsBackend::RpbIndexResp.new keys: %w{'asdf'}, done: true)
70
44
 
71
45
  blk = proc{:asdf}
72
46
 
@@ -74,7 +48,7 @@ describe Riak::Client::BeefcakeProtobuffsBackend do
74
48
  end
75
49
 
76
50
  it "should send batches of results to the block" do
77
- backend.should_receive(:write_protobuff)
51
+ expect(protocol).to receive(:write)
78
52
 
79
53
  response_sets = [%w{asdf asdg asdh}, %w{gggg gggh gggi}]
80
54
  response_messages = response_sets.map do |s|
@@ -82,17 +56,11 @@ describe Riak::Client::BeefcakeProtobuffsBackend do
82
56
  end
83
57
  response_messages.last.done = true
84
58
 
85
- response_chunks = response_messages.map do |m|
86
- encoded = m.encode
87
- header = [encoded.length + 1, 26].pack 'NC'
88
- [header, encoded]
89
- end.flatten
90
-
91
- @socket.should_receive(:read).and_return(*response_chunks)
59
+ expect(protocol).to receive(:expect).and_return(*response_messages)
92
60
 
93
- block_body = mock 'block'
94
- block_body.should_receive(:check).with(response_sets.first).once
95
- block_body.should_receive(:check).with(response_sets.last).once
61
+ block_body = double 'block'
62
+ expect(block_body).to receive(:check).with(response_sets.first).once
63
+ expect(block_body).to receive(:check).with(response_sets.last).once
96
64
 
97
65
  blk = proc {|m| block_body.check m }
98
66
 
@@ -101,44 +69,40 @@ describe Riak::Client::BeefcakeProtobuffsBackend do
101
69
  end
102
70
 
103
71
  it "should return a full batch of results when not streaming" do
104
- backend.should_receive(:write_protobuff) do |msg, req|
105
- msg.should == :IndexReq
106
- req[:stream].should_not be
72
+ expect(protocol).to receive(:write) do |msg, req|
73
+ expect(msg).to eq(:IndexReq)
74
+ expect(req[:stream]).not_to be
107
75
  end
108
76
 
109
77
  response_message = Riak::Client::BeefcakeProtobuffsBackend::
110
78
  RpbIndexResp.new(
111
79
  keys: %w{asdf asdg asdh}
112
- ).encode
113
- header = [response_message.length + 1, 26].pack 'NC'
114
- @socket.should_receive(:read).and_return(header, response_message)
80
+ )
81
+ expect(protocol).to receive(:expect).
82
+ and_return(response_message)
115
83
 
116
84
  results = backend.get_index 'bucket', 'words', 'asdf'..'hjkl'
117
- results.should == %w{asdf asdg asdh}
85
+ expect(results).to eq(%w{asdf asdg asdh})
118
86
  end
119
87
 
120
88
  it "should not crash out when no keys or terms are returned" do
121
- backend.should_receive(:write_protobuff) do |msg, req|
122
- msg.should == :IndexReq
123
- req[:stream].should_not be
89
+ expect(protocol).to receive(:write) do |msg, req|
90
+ expect(msg).to eq(:IndexReq)
91
+ expect(req[:stream]).not_to be
124
92
  end
125
93
 
126
94
  response_message = Riak::Client::BeefcakeProtobuffsBackend::
127
- RpbIndexResp.new().encode
95
+ RpbIndexResp.new()
128
96
 
129
- header = [response_message.length + 1, 26].pack 'NC'
130
- @socket.
131
- should_receive(:read).
132
- with(5).
133
- and_return(header)
97
+ expect(protocol).to receive(:expect).and_return(response_message)
134
98
 
135
99
  results = nil
136
100
  fetch = proc do
137
101
  results = backend.get_index 'bucket', 'words', 'asdf'
138
102
  end
139
103
 
140
- fetch.should_not raise_error
141
- results.should == []
104
+ expect(fetch).not_to raise_error
105
+ expect(results).to eq([])
142
106
  end
143
107
  end
144
108
 
@@ -146,20 +110,24 @@ describe Riak::Client::BeefcakeProtobuffsBackend do
146
110
  let(:mapred) { Riak::MapReduce.new(client).add('test').map("function(){}").map("function(){}") }
147
111
 
148
112
  it "should not return nil for previous phases that don't return anything" do
149
- socket = stub(:socket).as_null_object
150
- socket.stub(:read).and_return(stub(:socket_header, :unpack => [2, 24]), stub(:socket_message), stub(:socket_header_2, :unpack => [0, 1]))
151
- message = stub(:message, :phase => 1, :response => [{}].to_json)
152
- message.stub(:done).and_return(false, true)
153
- Riak::Client::BeefcakeProtobuffsBackend::RpbMapRedResp.stub(:decode => message)
154
- TCPSocket.stub(:new => socket)
155
- backend.send(:reset_socket)
156
-
157
- backend.mapred(mapred).should == [{}]
113
+ expect(protocol).to receive(:write)
114
+
115
+ message = double(:message, :phase => 1, :response => [{}].to_json)
116
+ allow(message).to receive(:done).and_return(false, true)
117
+
118
+ expect(protocol).to receive(:expect).
119
+ twice.
120
+ and_return(message)
121
+
122
+ expect(backend.mapred(mapred)).to eq([{}])
158
123
  end
159
124
  end
160
125
 
161
126
  context "preventing stale writes" do
162
- before { backend.stub(:decode_response => nil, :get_server_version => "1.0.3") }
127
+ before do
128
+ allow(backend).to receive(:decode_response).and_return(nil)
129
+ allow(backend).to receive(:get_server_version).and_return("1.0.3")
130
+ end
163
131
 
164
132
  let(:robject) do
165
133
  Riak::RObject.new(client['stale'], 'prevent').tap do |obj|
@@ -170,31 +138,25 @@ describe Riak::Client::BeefcakeProtobuffsBackend do
170
138
  end
171
139
 
172
140
  it "should set the if_none_match field when the object is new" do
173
- backend.should_receive(:write_protobuff) do |msg, req|
174
- msg.should == :PutReq
175
- req.if_none_match.should be_true
141
+ expect(protocol).to receive(:write) do |msg, req|
142
+ expect(msg).to eq(:PutReq)
143
+ expect(req.if_none_match).to be_truthy
176
144
  end
145
+ expect(protocol).to receive(:expect).
146
+ and_return(:empty)
147
+
177
148
  backend.store_object(robject)
178
149
  end
179
150
 
180
151
  it "should set the if_not_modified field when the object has a vclock" do
181
152
  robject.vclock = Base64.encode64("foo")
182
- backend.should_receive(:write_protobuff) do |msg, req|
183
- msg.should == :PutReq
184
- req.if_not_modified.should be_true
153
+ expect(protocol).to receive(:write) do |msg, req|
154
+ expect(msg).to eq(:PutReq)
155
+ expect(req.if_not_modified).to be_truthy
185
156
  end
157
+ expect(protocol).to receive(:expect).
158
+ and_return(:empty)
186
159
  backend.store_object(robject)
187
160
  end
188
-
189
- context "when conditional requests are not supported" do
190
- before { backend.stub(:get_server_version => "0.14.2") }
191
- let(:other) { robject.dup.tap {|o| o.vclock = 'bar' } }
192
-
193
- it "should fetch the original object and raise if not equivalent" do
194
- robject.vclock = Base64.encode64("foo")
195
- backend.should_receive(:fetch_object).and_return(other)
196
- expect { backend.store_object(robject) }.to raise_error(Riak::FailedRequest)
197
- end
198
- end
199
161
  end
200
162
  end