riak-client 2.5.0 → 2.6.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 +1 -0
- data/RELNOTES.md +3 -0
- data/lib/riak/bucket.rb +1 -1
- data/lib/riak/client.rb +14 -7
- data/lib/riak/client/beefcake/messages.rb +13 -0
- data/lib/riak/multi.rb +101 -0
- data/lib/riak/multiexist.rb +14 -0
- data/lib/riak/multiget.rb +7 -107
- data/lib/riak/version.rb +1 -1
- metadata +12 -234
- data/.document +0 -5
- data/.gitignore +0 -44
- data/.rspec +0 -2
- data/Gemfile +0 -17
- data/Guardfile +0 -20
- data/Rakefile +0 -124
- data/riak-client.gemspec +0 -71
- data/spec/failover/failover.rb +0 -59
- data/spec/fixtures/bitcask.txt +0 -25
- data/spec/fixtures/cat.jpg +0 -0
- data/spec/fixtures/multipart-basic-conflict.txt +0 -15
- data/spec/fixtures/multipart-blank.txt +0 -7
- data/spec/fixtures/multipart-mapreduce.txt +0 -10
- data/spec/fixtures/multipart-with-body.txt +0 -16
- data/spec/fixtures/multipart-with-marked-tombstones.txt +0 -17
- data/spec/fixtures/multipart-with-unmarked-tombstone.txt +0 -16
- data/spec/fixtures/server.cert.crt +0 -15
- data/spec/fixtures/server.cert.key +0 -15
- data/spec/fixtures/test.pem +0 -1
- data/spec/fixtures/yz_schema_template.xml +0 -18
- data/spec/integration/riak/bucket_types_spec.rb +0 -308
- data/spec/integration/riak/conflict_resolution_spec.rb +0 -96
- data/spec/integration/riak/counters_spec.rb +0 -36
- data/spec/integration/riak/crdt/configuration_spec.rb +0 -38
- data/spec/integration/riak/crdt_search_spec.rb +0 -176
- data/spec/integration/riak/crdt_spec.rb +0 -332
- data/spec/integration/riak/crdt_validation/map_spec.rb +0 -63
- data/spec/integration/riak/crdt_validation/set_spec.rb +0 -122
- data/spec/integration/riak/encodings/crdt_spec.rb +0 -122
- data/spec/integration/riak/encodings/kv_spec.rb +0 -87
- data/spec/integration/riak/encodings/yz_spec.rb +0 -142
- data/spec/integration/riak/preflist_spec.rb +0 -43
- data/spec/integration/riak/properties_spec.rb +0 -69
- data/spec/integration/riak/protobuffs/interrupted_request_spec.rb +0 -33
- data/spec/integration/riak/protobuffs/timeouts_spec.rb +0 -178
- data/spec/integration/riak/protobuffs_backends_spec.rb +0 -40
- data/spec/integration/riak/search_spec.rb +0 -104
- data/spec/integration/riak/secondary_index_spec.rb +0 -72
- data/spec/integration/riak/security_spec.rb +0 -105
- data/spec/integration/riak/threading_spec.rb +0 -154
- data/spec/integration/riak/time_series_spec.rb +0 -212
- data/spec/integration/yokozuna/index_spec.rb +0 -61
- data/spec/integration/yokozuna/queries_spec.rb +0 -115
- data/spec/integration/yokozuna/schema_spec.rb +0 -49
- data/spec/riak/beefcake_protobuffs_backend/bucket_properties_operator_spec.rb +0 -247
- data/spec/riak/beefcake_protobuffs_backend/crdt_operator_spec.rb +0 -244
- data/spec/riak/beefcake_protobuffs_backend/object_methods_spec.rb +0 -53
- data/spec/riak/beefcake_protobuffs_backend/protocol_spec.rb +0 -189
- data/spec/riak/beefcake_protobuffs_backend/ts_cell_codec_spec.rb +0 -124
- data/spec/riak/beefcake_protobuffs_backend_spec.rb +0 -162
- data/spec/riak/bucket_properties_spec.rb +0 -135
- data/spec/riak/bucket_spec.rb +0 -275
- data/spec/riak/bucket_type_spec.rb +0 -50
- data/spec/riak/bucket_typed/bucket_spec.rb +0 -78
- data/spec/riak/client_spec.rb +0 -304
- data/spec/riak/core_ext/to_param_spec.rb +0 -15
- data/spec/riak/counter_spec.rb +0 -122
- data/spec/riak/crdt/counter_spec.rb +0 -55
- data/spec/riak/crdt/hyper_log_log_spec.rb +0 -56
- data/spec/riak/crdt/inner_counter_spec.rb +0 -21
- data/spec/riak/crdt/inner_flag_spec.rb +0 -39
- data/spec/riak/crdt/inner_map_spec.rb +0 -47
- data/spec/riak/crdt/inner_register_spec.rb +0 -40
- data/spec/riak/crdt/inner_set_spec.rb +0 -33
- data/spec/riak/crdt/map_spec.rb +0 -78
- data/spec/riak/crdt/set_spec.rb +0 -61
- data/spec/riak/crdt/shared_examples.rb +0 -88
- data/spec/riak/crdt/typed_collection_spec.rb +0 -225
- data/spec/riak/escape_spec.rb +0 -72
- data/spec/riak/feature_detection_spec.rb +0 -77
- data/spec/riak/index_collection_spec.rb +0 -53
- data/spec/riak/instrumentation_spec.rb +0 -124
- data/spec/riak/link_spec.rb +0 -85
- data/spec/riak/list_buckets_spec.rb +0 -41
- data/spec/riak/map_reduce/filter_builder_spec.rb +0 -32
- data/spec/riak/map_reduce/phase_spec.rb +0 -142
- data/spec/riak/map_reduce_spec.rb +0 -434
- data/spec/riak/multiget_spec.rb +0 -81
- data/spec/riak/node_spec.rb +0 -26
- data/spec/riak/robject_spec.rb +0 -542
- data/spec/riak/search/index_spec.rb +0 -72
- data/spec/riak/search/query_spec.rb +0 -88
- data/spec/riak/search/result_collection_spec.rb +0 -89
- data/spec/riak/search/result_document_spec.rb +0 -106
- data/spec/riak/search/schema_spec.rb +0 -63
- data/spec/riak/search_spec.rb +0 -107
- data/spec/riak/secondary_index_spec.rb +0 -225
- data/spec/riak/serializers_spec.rb +0 -121
- data/spec/riak/stamp_spec.rb +0 -54
- data/spec/riak/time_series/deletion_spec.rb +0 -33
- data/spec/riak/time_series/listing_spec.rb +0 -51
- data/spec/riak/time_series/submission_spec.rb +0 -35
- data/spec/riak/util/gzip_spec.rb +0 -49
- data/spec/riak/walk_spec_spec.rb +0 -203
- data/spec/spec_helper.rb +0 -67
- data/spec/support/certs/README.md +0 -13
- data/spec/support/certs/ca.crt +0 -21
- data/spec/support/certs/client.crl +0 -13
- data/spec/support/certs/client.crt +0 -94
- data/spec/support/certs/client.csr +0 -18
- data/spec/support/certs/client.key +0 -27
- data/spec/support/certs/empty_ca.crt +0 -21
- data/spec/support/certs/server.crl +0 -13
- data/spec/support/certs/server.crt +0 -94
- data/spec/support/certs/server.key +0 -27
- data/spec/support/crdt_search_config.rb +0 -112
- data/spec/support/crdt_search_fixtures.rb +0 -42
- data/spec/support/integration_setup.rb +0 -10
- data/spec/support/search_config.rb +0 -83
- data/spec/support/search_corpus_setup.rb +0 -39
- data/spec/support/test_client.rb +0 -52
- data/spec/support/test_client.yml.example +0 -10
- data/spec/support/unified_backend_examples.rb +0 -402
- data/spec/support/version_filter.rb +0 -12
- data/spec/support/wait_until.rb +0 -20
data/spec/riak/node_spec.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Riak::Client::Node do
|
4
|
-
before :each do
|
5
|
-
@client = Riak::Client.new
|
6
|
-
@node = Riak::Client::Node.new @client
|
7
|
-
end
|
8
|
-
|
9
|
-
describe 'when initializing' do
|
10
|
-
it 'defaults to the local interface on port 8087' do
|
11
|
-
node = Riak::Client::Node.new @client
|
12
|
-
expect(node.host).to eq('127.0.0.1')
|
13
|
-
expect(node.pb_port).to eq(8087)
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'accepts a host' do
|
17
|
-
node = Riak::Client::Node.new(@client, :host => 'riak.basho.com')
|
18
|
-
expect(node.host).to eq("riak.basho.com")
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'accepts a Protobuffs port' do
|
22
|
-
node = Riak::Client::Node.new @client, :pb_port => 9000
|
23
|
-
expect(node.pb_port).to eq(9000)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
data/spec/riak/robject_spec.rb
DELETED
@@ -1,542 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Riak::RObject do
|
4
|
-
before :each do
|
5
|
-
@client = Riak::Client.new
|
6
|
-
@bucket = Riak::Bucket.new(@client, "foo")
|
7
|
-
end
|
8
|
-
|
9
|
-
describe "initialization" do
|
10
|
-
it "sets the bucket" do
|
11
|
-
@object = Riak::RObject.new(@bucket, "bar")
|
12
|
-
expect(@object.bucket).to eq(@bucket)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "sets the key" do
|
16
|
-
@object = Riak::RObject.new(@bucket, "bar")
|
17
|
-
expect(@object.key).to eq("bar")
|
18
|
-
end
|
19
|
-
|
20
|
-
it "initializes the links to an empty set" do
|
21
|
-
@object = Riak::RObject.new(@bucket, "bar")
|
22
|
-
expect(@object.links).to eq(Set.new)
|
23
|
-
end
|
24
|
-
|
25
|
-
it "initializes the meta to an empty hash" do
|
26
|
-
@object = Riak::RObject.new(@bucket, "bar")
|
27
|
-
expect(@object.meta).to eq({})
|
28
|
-
end
|
29
|
-
|
30
|
-
it "initializes indexes to an empty hash with a Set for the default value" do
|
31
|
-
@object = Riak::RObject.new(@bucket, "bar")
|
32
|
-
expect(@object.indexes).to be_kind_of(Hash)
|
33
|
-
expect(@object.indexes).to be_empty
|
34
|
-
expect(@object.indexes['foo_bin']).to be_kind_of(Set)
|
35
|
-
end
|
36
|
-
|
37
|
-
it "yields itself to a given block" do
|
38
|
-
Riak::RObject.new(@bucket, "bar") do |r|
|
39
|
-
expect(r.key).to eq("bar")
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
describe "serialization" do
|
45
|
-
before :each do
|
46
|
-
@object = Riak::RObject.new(@bucket, "bar")
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'delegates #serialize to the appropriate serializer for the content type' do
|
50
|
-
@object.content_type = 'text/plain'
|
51
|
-
expect(Riak::Serializers).to respond_to(:serialize).with(2).arguments
|
52
|
-
expect(Riak::Serializers).to receive(:serialize).with('text/plain', "foo").and_return("serialized foo")
|
53
|
-
expect(@object.content.serialize("foo")).to eq("serialized foo")
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'delegates #deserialize to the appropriate serializer for the content type' do
|
57
|
-
@object.content_type = 'text/plain'
|
58
|
-
expect(Riak::Serializers).to respond_to(:deserialize).with(2).arguments
|
59
|
-
expect(Riak::Serializers).to receive(:deserialize).with('text/plain', "foo").and_return("deserialized foo")
|
60
|
-
expect(@object.content.deserialize("foo")).to eq("deserialized foo")
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
describe "data access methods" do
|
65
|
-
before :each do
|
66
|
-
@object = Riak::RObject.new(@bucket, "bar")
|
67
|
-
@object.content_type = "application/json"
|
68
|
-
end
|
69
|
-
|
70
|
-
describe "for raw data" do
|
71
|
-
describe "when unserialized data was already provided" do
|
72
|
-
before do
|
73
|
-
@object.data = { 'some' => 'data' }
|
74
|
-
end
|
75
|
-
|
76
|
-
it "resets unserialized forms when stored" do
|
77
|
-
@object.raw_data = value = '{ "raw": "json" }'
|
78
|
-
|
79
|
-
expect(@object.raw_data).to eq(value)
|
80
|
-
expect(@object.data).to eq({ "raw" => "json" })
|
81
|
-
end
|
82
|
-
|
83
|
-
it "lazily serializes when read" do
|
84
|
-
expect(@object.raw_data).to eq('{"some":"data"}')
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
it "only marshal/demarshals when necessary" do
|
89
|
-
expect(@object).not_to receive(:serialize)
|
90
|
-
expect(@object).not_to receive(:deserialize)
|
91
|
-
@object.raw_data = value = "{not even valid json!}}"
|
92
|
-
expect(@object.raw_data).to eq(value)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
describe "for unserialized data" do
|
97
|
-
describe "when raw data was already provided" do
|
98
|
-
before do
|
99
|
-
@object.raw_data = '{"some":"data"}'
|
100
|
-
end
|
101
|
-
|
102
|
-
it "resets previously stored raw data" do
|
103
|
-
@object.data = value = { "new" => "data" }
|
104
|
-
expect(@object.raw_data).to eq('{"new":"data"}')
|
105
|
-
expect(@object.data).to eq(value)
|
106
|
-
end
|
107
|
-
|
108
|
-
it "lazily deserializes when read" do
|
109
|
-
expect(@object.data).to eq({ "some" => "data" })
|
110
|
-
end
|
111
|
-
|
112
|
-
context 'for an IO-like object' do
|
113
|
-
let(:io_object) { double(:read => 'the io object') }
|
114
|
-
|
115
|
-
it 'reads the object before deserializing it' do
|
116
|
-
expect(@object.content).to receive(:deserialize).with('the io object').and_return('deserialized')
|
117
|
-
@object.raw_data = io_object
|
118
|
-
expect(@object.data).to eq('deserialized')
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'does not allow it to be assigned directly to data' do
|
122
|
-
# it should be assigned to raw_data instead
|
123
|
-
expect {
|
124
|
-
@object.data = io_object
|
125
|
-
}.to raise_error(ArgumentError)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
it "only marshal/demarshals when necessary" do
|
131
|
-
expect(@object).not_to receive(:serialize)
|
132
|
-
expect(@object).not_to receive(:deserialize)
|
133
|
-
@object.data = value = { "some" => "data" }
|
134
|
-
expect(@object.data).to eq(value)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
|
140
|
-
describe "instantiating new object from a map reduce operation" do
|
141
|
-
before :each do
|
142
|
-
allow(@client).to receive(:[]).and_return(@bucket)
|
143
|
-
|
144
|
-
@sample_response = [
|
145
|
-
{"bucket"=>"users",
|
146
|
-
"key"=>"A2IbUQ2KEMbe4WGtdL97LoTi1DN%5B%28%5C%2F%29%5D",
|
147
|
-
"vclock"=> "a85hYGBgzmDKBVIsCfs+fc9gSN9wlA8q/hKosDpIOAsA",
|
148
|
-
"values"=> [
|
149
|
-
{"metadata"=>
|
150
|
-
{"Links"=>[%w(addresses A2cbUQ2KEMbeyWGtdz97LoTi1DN home_address)],
|
151
|
-
"X-Riak-VTag"=>"5bnavU3rrubcxLI8EvFXhB",
|
152
|
-
"content-type"=>"application/json",
|
153
|
-
"X-Riak-Last-Modified"=>"Mon, 12 Jul 2010 21:37:43 GMT",
|
154
|
-
"X-Riak-Meta"=>{"X-Riak-Meta-King-Of-Robots"=>"I"},
|
155
|
-
"index" => {
|
156
|
-
"email_bin" => ["sean@basho.com", "seancribbs@gmail.com"],
|
157
|
-
"rank_int" => 50
|
158
|
-
}
|
159
|
-
},
|
160
|
-
"data"=>
|
161
|
-
"{\"email\":\"mail@test.com\",\"_type\":\"User\"}"
|
162
|
-
}
|
163
|
-
]
|
164
|
-
}
|
165
|
-
]
|
166
|
-
@object = Riak::RObject.load_from_mapreduce(@client, @sample_response).first
|
167
|
-
expect(@object).to be_kind_of(Riak::RObject)
|
168
|
-
end
|
169
|
-
|
170
|
-
it "loads the content type" do
|
171
|
-
expect(@object.content_type).to eq("application/json")
|
172
|
-
end
|
173
|
-
|
174
|
-
it "loads the body data" do
|
175
|
-
expect(@object.data).to be_present
|
176
|
-
end
|
177
|
-
|
178
|
-
it "deserializes the body data" do
|
179
|
-
expect(@object.data).to eq({"email" => "mail@test.com", "_type" => "User"})
|
180
|
-
end
|
181
|
-
|
182
|
-
it "sets the vclock" do
|
183
|
-
expect(@object.vclock).to eq("a85hYGBgzmDKBVIsCfs+fc9gSN9wlA8q/hKosDpIOAsA")
|
184
|
-
expect(@object.causal_context).to eq @object.vclock
|
185
|
-
end
|
186
|
-
|
187
|
-
it "loads and parse links" do
|
188
|
-
expect(@object.links.size).to eq(1)
|
189
|
-
expect(@object.links.first.url).to eq("/riak/addresses/A2cbUQ2KEMbeyWGtdz97LoTi1DN")
|
190
|
-
expect(@object.links.first.rel).to eq("home_address")
|
191
|
-
end
|
192
|
-
|
193
|
-
it "loads and parse indexes" do
|
194
|
-
expect(@object.indexes.size).to eq(2)
|
195
|
-
expect(@object.indexes['email_bin'].size).to eq(2)
|
196
|
-
expect(@object.indexes['rank_int'].size).to eq(1)
|
197
|
-
end
|
198
|
-
|
199
|
-
it "sets the ETag" do
|
200
|
-
expect(@object.etag).to eq("5bnavU3rrubcxLI8EvFXhB")
|
201
|
-
end
|
202
|
-
|
203
|
-
it "sets modified date" do
|
204
|
-
expect(@object.last_modified.to_i).to eq(Time.httpdate("Mon, 12 Jul 2010 21:37:43 GMT").to_i)
|
205
|
-
end
|
206
|
-
|
207
|
-
it "loads meta information" do
|
208
|
-
expect(@object.meta["King-Of-Robots"]).to eq(["I"])
|
209
|
-
end
|
210
|
-
|
211
|
-
it "sets the key" do
|
212
|
-
expect(@object.key).to eq("A2IbUQ2KEMbe4WGtdL97LoTi1DN[(\\/)]")
|
213
|
-
end
|
214
|
-
|
215
|
-
it "doesn't set conflict when there is none" do
|
216
|
-
expect(@object.conflict?).to be_falsey
|
217
|
-
end
|
218
|
-
|
219
|
-
it "doesn't set tombstone when there is none" do
|
220
|
-
expect(@object.tombstone?).to be_falsey
|
221
|
-
end
|
222
|
-
|
223
|
-
it 'returns [RContent] for siblings' do
|
224
|
-
expect(@object.siblings).to eq([@object.content])
|
225
|
-
end
|
226
|
-
|
227
|
-
describe "when there are multiple values in an object" do
|
228
|
-
before :each do
|
229
|
-
response = @sample_response.dup
|
230
|
-
response[0]['values'] << {
|
231
|
-
"metadata"=> {
|
232
|
-
"Links"=>[],
|
233
|
-
"X-Riak-VTag"=>"7jDZLdu0fIj2iRsjGD8qq8",
|
234
|
-
"content-type"=>"application/json",
|
235
|
-
"X-Riak-Last-Modified"=>"Mon, 14 Jul 2010 19:28:27 GMT",
|
236
|
-
"X-Riak-Meta"=>[]
|
237
|
-
},
|
238
|
-
"data"=> "{\"email\":\"mail@domain.com\",\"_type\":\"User\"}"
|
239
|
-
}
|
240
|
-
@object = Riak::RObject.load_from_mapreduce( @client, response ).first
|
241
|
-
end
|
242
|
-
|
243
|
-
it "exposes siblings" do
|
244
|
-
expect(@object.siblings.size).to eq(2)
|
245
|
-
expect(@object.siblings[0].etag).to eq("5bnavU3rrubcxLI8EvFXhB")
|
246
|
-
expect(@object.siblings[1].etag).to eq("7jDZLdu0fIj2iRsjGD8qq8")
|
247
|
-
end
|
248
|
-
|
249
|
-
it "raises the conflict? flag when in conflict" do
|
250
|
-
expect { @object.data }.to raise_error(Riak::Conflict)
|
251
|
-
expect(@object).to be_conflict
|
252
|
-
end
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
it "doesn't allow duplicate links" do
|
257
|
-
@object = Riak::RObject.new(@bucket, "foo")
|
258
|
-
@object.links << Riak::Link.new("/riak/foo/baz", "next")
|
259
|
-
@object.links << Riak::Link.new("/riak/foo/baz", "next")
|
260
|
-
expect(@object.links.length).to eq(1)
|
261
|
-
end
|
262
|
-
|
263
|
-
it "allows mass-overwriting indexes while preserving default behavior" do
|
264
|
-
@object = described_class.new(@bucket, 'foo')
|
265
|
-
@object.indexes = {"ts_int" => [12345], "foo_bin" => "bar"}
|
266
|
-
expect(@object.indexes['ts_int']).to eq(Set.new([12345]))
|
267
|
-
expect(@object.indexes['foo_bin']).to eq(Set.new(["bar"]))
|
268
|
-
expect(@object.indexes['unset_bin']).to eq(Set.new)
|
269
|
-
end
|
270
|
-
|
271
|
-
describe "when storing the object normally" do
|
272
|
-
before :each do
|
273
|
-
@backend = double("Backend")
|
274
|
-
allow(@client).to receive(:backend).and_yield(@backend)
|
275
|
-
@object = Riak::RObject.new(@bucket)
|
276
|
-
@object.content_type = "text/plain"
|
277
|
-
@object.data = "This is some text."
|
278
|
-
# @headers = @object.store_headers
|
279
|
-
end
|
280
|
-
|
281
|
-
it "raises an error when the content_type is blank" do
|
282
|
-
expect do
|
283
|
-
@object.content_type = nil
|
284
|
-
@object.store
|
285
|
-
end.to raise_error(ArgumentError)
|
286
|
-
expect do
|
287
|
-
@object.content_type = ' '
|
288
|
-
@object.store
|
289
|
-
end.to raise_error(ArgumentError)
|
290
|
-
end
|
291
|
-
|
292
|
-
it "raises an error when given an empty string as key" do
|
293
|
-
expect do
|
294
|
-
@object.key = ''
|
295
|
-
@object.store
|
296
|
-
end.to raise_error(ArgumentError)
|
297
|
-
end
|
298
|
-
|
299
|
-
it "passes quorum parameters and returnbody to the backend" do
|
300
|
-
@object.key = 'foo'
|
301
|
-
expect(@backend).to receive(:store_object).
|
302
|
-
with(@object,
|
303
|
-
returnbody: false,
|
304
|
-
w: 3,
|
305
|
-
dw: 2).
|
306
|
-
and_return(true)
|
307
|
-
@object.store(returnbody: false, w: 3, dw: 2)
|
308
|
-
end
|
309
|
-
|
310
|
-
it "raises an error if the object is in conflict" do
|
311
|
-
@object.siblings << Riak::RContent.new(@object)
|
312
|
-
expect { @object.store }.to raise_error(Riak::Conflict)
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
316
|
-
describe "when reloading the object" do
|
317
|
-
before :each do
|
318
|
-
@backend = double("Backend")
|
319
|
-
allow(@client).to receive(:backend).and_yield(@backend)
|
320
|
-
@object = Riak::RObject.new(@bucket, "bar")
|
321
|
-
@object.vclock = "somereallylongstring"
|
322
|
-
end
|
323
|
-
|
324
|
-
it "returns without requesting if the key is blank" do
|
325
|
-
@object.key = nil
|
326
|
-
expect(@backend).not_to receive(:reload_object)
|
327
|
-
@object.reload
|
328
|
-
end
|
329
|
-
|
330
|
-
it "returns without requesting if the vclock is blank" do
|
331
|
-
@object.vclock = nil
|
332
|
-
expect(@backend).not_to receive(:reload_object)
|
333
|
-
@object.reload
|
334
|
-
end
|
335
|
-
|
336
|
-
it "reloads the object if the key is present" do
|
337
|
-
expect(@backend).to receive(:reload_object).with(@object, {}).and_return(@object)
|
338
|
-
@object.reload
|
339
|
-
end
|
340
|
-
|
341
|
-
it "passes the requested R quorum to the backend" do
|
342
|
-
expect(@backend).to receive(:reload_object).with(@object, :r => 2).and_return(@object)
|
343
|
-
@object.reload :r => 2
|
344
|
-
end
|
345
|
-
|
346
|
-
it "disables matching conditions if the key is present and the :force option is given" do
|
347
|
-
expect(@backend).to receive(:reload_object) do |obj, _|
|
348
|
-
expect(obj.etag).to be_nil
|
349
|
-
expect(obj.last_modified).to be_nil
|
350
|
-
obj
|
351
|
-
end
|
352
|
-
@object.reload :force => true
|
353
|
-
end
|
354
|
-
end
|
355
|
-
|
356
|
-
describe "when deleting" do
|
357
|
-
before :each do
|
358
|
-
@backend = double("Backend")
|
359
|
-
allow(@client).to receive(:backend).and_yield(@backend)
|
360
|
-
@object = Riak::RObject.new(@bucket, "bar")
|
361
|
-
end
|
362
|
-
|
363
|
-
it "makes a DELETE request to the Riak server and freeze the object" do
|
364
|
-
expect(@backend).to receive(:delete_object).with(@bucket, "bar", {})
|
365
|
-
@object.delete
|
366
|
-
expect(@object).to be_frozen
|
367
|
-
end
|
368
|
-
|
369
|
-
it "does nothing when the key is blank" do
|
370
|
-
expect(@backend).not_to receive(:delete_object)
|
371
|
-
@object.key = nil
|
372
|
-
@object.delete
|
373
|
-
end
|
374
|
-
|
375
|
-
it "raises a failed request exception when the backend returns a server error" do
|
376
|
-
expect(@backend).to receive(:delete_object).
|
377
|
-
and_raise(Riak::ProtobuffsFailedRequest.new(:server_error, "server error"))
|
378
|
-
expect { @object.delete }.to raise_error(Riak::FailedRequest)
|
379
|
-
end
|
380
|
-
|
381
|
-
it "sends the vector clock to the backend if present" do
|
382
|
-
@object.vclock = "somevclock"
|
383
|
-
expect(@backend).to receive(:delete_object).with(@bucket, "bar", {:vclock => "somevclock"})
|
384
|
-
@object.delete
|
385
|
-
end
|
386
|
-
end
|
387
|
-
|
388
|
-
it "doesn't convert to link without a tag" do
|
389
|
-
@object = Riak::RObject.new(@bucket, "bar")
|
390
|
-
expect { @object.to_link }.to raise_error
|
391
|
-
end
|
392
|
-
|
393
|
-
it "converts to a link having the same url and a supplied tag" do
|
394
|
-
@object = Riak::RObject.new(@bucket, "bar")
|
395
|
-
expect(@object.to_link("next")).to eq(Riak::Link.new("/riak/foo/bar", "next"))
|
396
|
-
end
|
397
|
-
|
398
|
-
it "escapes the bucket and key when converting to a link" do
|
399
|
-
@object = Riak::RObject.new(@bucket, "deep/path")
|
400
|
-
expect(@bucket).to receive(:name).and_return("bucket spaces")
|
401
|
-
expect(@object.to_link("bar").url).to eq("/riak/bucket%20spaces/deep%2Fpath")
|
402
|
-
end
|
403
|
-
|
404
|
-
describe "#inspect" do
|
405
|
-
let(:object) { Riak::RObject.new(@bucket) }
|
406
|
-
|
407
|
-
it "provides useful output even when the key is nil" do
|
408
|
-
expect { object.inspect }.not_to raise_error
|
409
|
-
expect(object.inspect).to be_kind_of(String)
|
410
|
-
end
|
411
|
-
|
412
|
-
it 'uses the serializer output in inspect' do
|
413
|
-
object.raw_data = { 'a' => 7 }
|
414
|
-
object.content_type = 'inspect/type'
|
415
|
-
Riak::Serializers['inspect/type'] = Object.new.tap do |o|
|
416
|
-
def o.load(object)
|
417
|
-
"serialize for inspect"
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
expect(object.inspect).to match(/serialize for inspect/)
|
422
|
-
end
|
423
|
-
end
|
424
|
-
|
425
|
-
describe '.on_conflict' do
|
426
|
-
it 'adds the hook to the list of on conflict hooks' do
|
427
|
-
hook_run = false
|
428
|
-
expect(described_class.on_conflict_hooks).to be_empty
|
429
|
-
described_class.on_conflict { hook_run = true }
|
430
|
-
expect(described_class.on_conflict_hooks.size).to eq(1)
|
431
|
-
described_class.on_conflict_hooks.first.call
|
432
|
-
expect(hook_run).to eq(true)
|
433
|
-
end
|
434
|
-
end
|
435
|
-
|
436
|
-
describe '#attempt_conflict_resolution' do
|
437
|
-
let(:conflicted_robject) do
|
438
|
-
Riak::RObject.new(@bucket, "conflicted") do |r|
|
439
|
-
r.siblings = [ Riak::RContent.new(r), Riak::RContent.new(r)]
|
440
|
-
end
|
441
|
-
end
|
442
|
-
let(:resolved_robject) { Riak::RObject.new(@bucket, "resolved") }
|
443
|
-
let(:invoked_resolvers) { [] }
|
444
|
-
let(:resolver_1) do
|
445
|
-
lambda do |r|
|
446
|
-
invoked_resolvers << :resolver_1
|
447
|
-
nil
|
448
|
-
end
|
449
|
-
end
|
450
|
-
let(:resolver_2) do
|
451
|
-
lambda do |r|
|
452
|
-
invoked_resolvers << :resolver_2
|
453
|
-
:not_an_robject
|
454
|
-
end
|
455
|
-
end
|
456
|
-
let(:resolver_3) do
|
457
|
-
lambda do |r|
|
458
|
-
invoked_resolvers << :resolver_3
|
459
|
-
r
|
460
|
-
end
|
461
|
-
end
|
462
|
-
let(:resolver_4) do
|
463
|
-
lambda do |r|
|
464
|
-
invoked_resolvers << :resolver_4
|
465
|
-
resolved_robject
|
466
|
-
end
|
467
|
-
end
|
468
|
-
|
469
|
-
before(:each) do
|
470
|
-
described_class.on_conflict(&resolver_1)
|
471
|
-
described_class.on_conflict(&resolver_2)
|
472
|
-
end
|
473
|
-
|
474
|
-
it 'calls each resolver until one of them returns an robject' do
|
475
|
-
described_class.on_conflict(&resolver_3)
|
476
|
-
described_class.on_conflict(&resolver_4)
|
477
|
-
conflicted_robject.attempt_conflict_resolution
|
478
|
-
expect(invoked_resolvers).to eq([:resolver_1, :resolver_2, :resolver_3])
|
479
|
-
end
|
480
|
-
|
481
|
-
it 'returns the robject returned by the last invoked resolver' do
|
482
|
-
described_class.on_conflict(&resolver_4)
|
483
|
-
expect(conflicted_robject.attempt_conflict_resolution).to be(resolved_robject)
|
484
|
-
end
|
485
|
-
|
486
|
-
it 'allows the resolver to return the original robject' do
|
487
|
-
described_class.on_conflict(&resolver_3)
|
488
|
-
expect(conflicted_robject.attempt_conflict_resolution).to be(conflicted_robject)
|
489
|
-
end
|
490
|
-
|
491
|
-
it 'returns the robject and does not call any resolvers if the robject is not in conflict' do
|
492
|
-
expect(resolved_robject.attempt_conflict_resolution).to be(resolved_robject)
|
493
|
-
expect(invoked_resolvers).to eq([])
|
494
|
-
end
|
495
|
-
|
496
|
-
it 'returns the original robject if none of the resolvers returns an robject' do
|
497
|
-
expect(conflicted_robject.attempt_conflict_resolution).to be(conflicted_robject)
|
498
|
-
expect(invoked_resolvers).to eq([:resolver_1, :resolver_2])
|
499
|
-
end
|
500
|
-
end
|
501
|
-
|
502
|
-
describe "when working with a tombstone object" do
|
503
|
-
before :each do
|
504
|
-
@backend = double("Backend")
|
505
|
-
allow(@client).to receive(:backend).and_yield(@backend)
|
506
|
-
@object =Riak::RObject.new(@bucket)
|
507
|
-
@object.siblings.clear
|
508
|
-
@object.vclock = "notnil"
|
509
|
-
end
|
510
|
-
|
511
|
-
it "sets the tombstone flag" do
|
512
|
-
expect(@object.tombstone?).to be true
|
513
|
-
end
|
514
|
-
|
515
|
-
it "does not set the conflict flag" do
|
516
|
-
expect(@object.conflict?).to be_falsey
|
517
|
-
end
|
518
|
-
|
519
|
-
it "does not allow you to store a tombstone" do
|
520
|
-
expect { @object.store }.to raise_error(Riak::Tombstone)
|
521
|
-
end
|
522
|
-
|
523
|
-
it "does not allow you to fetch a value" do
|
524
|
-
expect { @object.content }.to raise_error(Riak::Tombstone)
|
525
|
-
end
|
526
|
-
|
527
|
-
it "allows you to revive the object" do
|
528
|
-
@object.revive
|
529
|
-
expect(@object.tombstone?).to be_falsey
|
530
|
-
expect(@object.siblings.empty?).to be_falsey
|
531
|
-
end
|
532
|
-
|
533
|
-
it "allows revived objects to be stored" do
|
534
|
-
expect(@object.tombstone?).to be true
|
535
|
-
@object.revive
|
536
|
-
@object.content_type = "text/plain"
|
537
|
-
@object.data = "This is some text."
|
538
|
-
expect(@backend).to receive(:store_object).and_return(true)
|
539
|
-
@object.store
|
540
|
-
end
|
541
|
-
end
|
542
|
-
end
|