riak-client 1.0.5 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +4 -3
- data/.rspec +1 -0
- data/Gemfile +1 -0
- data/RELEASE_NOTES.md +47 -0
- data/Rakefile +0 -1
- data/erl_src/riak_kv_test_backend.erl +34 -0
- data/lib/riak/client.rb +3 -1
- data/lib/riak/client/beefcake/messages.rb +49 -1
- data/lib/riak/client/beefcake/object_methods.rb +14 -21
- data/lib/riak/client/beefcake_protobuffs_backend.rb +58 -12
- data/lib/riak/client/decaying.rb +31 -23
- data/lib/riak/client/feature_detection.rb +88 -0
- data/lib/riak/client/http_backend.rb +27 -6
- data/lib/riak/client/http_backend/configuration.rb +13 -0
- data/lib/riak/client/http_backend/object_methods.rb +33 -25
- data/lib/riak/client/node.rb +7 -2
- data/lib/riak/client/protobuffs_backend.rb +54 -3
- data/lib/riak/client/search.rb +2 -2
- data/lib/riak/conflict.rb +13 -0
- data/lib/riak/locale/en.yml +2 -0
- data/lib/riak/map_reduce.rb +1 -1
- data/lib/riak/map_reduce/filter_builder.rb +2 -2
- data/lib/riak/map_reduce/results.rb +49 -0
- data/lib/riak/node/console.rb +17 -16
- data/lib/riak/node/generation.rb +9 -0
- data/lib/riak/rcontent.rb +168 -0
- data/lib/riak/robject.rb +37 -157
- data/lib/riak/util/escape.rb +5 -1
- data/lib/riak/version.rb +1 -1
- data/riak-client.gemspec +37 -5
- data/spec/fixtures/multipart-basic-conflict.txt +15 -0
- data/spec/fixtures/munchausen.txt +1033 -0
- data/spec/integration/riak/cluster_spec.rb +1 -1
- data/spec/integration/riak/http_backends_spec.rb +23 -2
- data/spec/integration/riak/node_spec.rb +2 -2
- data/spec/integration/riak/protobuffs_backends_spec.rb +17 -2
- data/spec/integration/riak/test_server_spec.rb +1 -1
- data/spec/integration/riak/threading_spec.rb +3 -3
- data/spec/riak/beefcake_protobuffs_backend_spec.rb +58 -25
- data/spec/riak/escape_spec.rb +3 -0
- data/spec/riak/feature_detection_spec.rb +61 -0
- data/spec/riak/http_backend/object_methods_spec.rb +4 -13
- data/spec/riak/http_backend_spec.rb +6 -5
- data/spec/riak/map_reduce_spec.rb +0 -5
- data/spec/riak/robject_spec.rb +12 -11
- data/spec/spec_helper.rb +3 -1
- data/spec/support/riak_test.rb +77 -0
- data/spec/support/search_corpus_setup.rb +18 -0
- data/spec/support/sometimes.rb +1 -1
- data/spec/support/test_server.rb +1 -1
- data/spec/support/unified_backend_examples.rb +53 -7
- data/spec/support/version_filter.rb +4 -11
- metadata +56 -22
- data/lib/riak/client/pool.rb +0 -180
- data/spec/riak/pool_spec.rb +0 -306
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'riak/cluster'
|
3
3
|
|
4
|
-
describe Riak::Cluster, :test_server => false, :slow => true do
|
4
|
+
describe Riak::Cluster, :test_server => false, :slow => true, :nodegen => true do
|
5
5
|
let(:config) { YAML.load_file("spec/support/test_server.yml").symbolize_keys }
|
6
6
|
subject { described_class.new(config) }
|
7
7
|
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe "HTTP" do
|
4
4
|
before do
|
5
|
-
@web_port =
|
5
|
+
@web_port = test_server.http_port
|
6
6
|
@client = Riak::Client.new(:http_port => @web_port)
|
7
7
|
end
|
8
8
|
|
@@ -16,7 +16,28 @@ describe "HTTP" do
|
|
16
16
|
|
17
17
|
it_should_behave_like "Unified backend API"
|
18
18
|
|
19
|
-
describe "
|
19
|
+
describe "searching fulltext indexes (1.1 and earlier)", :version => "< 1.2.0" do
|
20
|
+
include_context "search corpus setup"
|
21
|
+
|
22
|
+
it 'should find indexed documents, returning ids' do
|
23
|
+
results = @backend.search 'search_test', 'fearless elephant rushed', :fl => 'id'
|
24
|
+
results.should have_key 'docs'
|
25
|
+
results.should have_key 'max_score'
|
26
|
+
results.should have_key 'num_found'
|
27
|
+
results['docs'].should include({"id" => "munchausen-605"})
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should find indexed documents, returning documents' do
|
31
|
+
# For now use '*' until #122 is merged into riak_search
|
32
|
+
results = @backend.search 'search_test', 'fearless elephant rushed', :fl => '*'
|
33
|
+
results.should have_key 'docs'
|
34
|
+
results.should have_key 'max_score'
|
35
|
+
results.should have_key 'num_found'
|
36
|
+
results['docs'].should include({"id" => "munchausen-605", "value" => "Fearless I advanced against the elephant, desirous to take alive the haughty Tippoo Sahib; but he drew a pistol from his belt, and discharged it full in my face as I rushed upon him, which did me no further harm than wound my cheek-bone, which disfigures me somewhat under my left eye. I could not withstand the rage and impulse of that moment, and with one blow of my sword separated his head from his body.\n"})
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "using Luwak", :version => "< 1.1.0" do
|
20
41
|
let(:file) { File.open(__FILE__) }
|
21
42
|
let(:key) { "spec.rb" }
|
22
43
|
let(:string) { file.read }
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
require 'riak/node'
|
3
3
|
require 'yaml'
|
4
4
|
|
5
|
-
describe Riak::Node, :test_server => false, :slow => true do
|
5
|
+
describe Riak::Node, :test_server => false, :slow => true, :nodegen => true do
|
6
6
|
let(:test_server_config){ YAML.load_file("spec/support/test_server.yml") }
|
7
7
|
let(:node){ described_class.new(:root => ".ripplenode", :source => test_server_config['source']) }
|
8
8
|
subject { node }
|
@@ -173,7 +173,7 @@ describe Riak::Node, :test_server => false, :slow => true do
|
|
173
173
|
expect {
|
174
174
|
console.command "ok."
|
175
175
|
console.close
|
176
|
-
}.
|
176
|
+
}.to_not raise_error
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
@@ -2,8 +2,9 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe "Protocol Buffers" do
|
4
4
|
before do
|
5
|
-
@pbc_port ||=
|
6
|
-
@
|
5
|
+
@pbc_port ||= test_server.pb_port
|
6
|
+
@http_port ||= test_server.http_port
|
7
|
+
@client = Riak::Client.new(:http_port => @http_port, :pb_port => @pbc_port, :protocol => "pbc")
|
7
8
|
end
|
8
9
|
|
9
10
|
[:BeefcakeProtobuffsBackend].each do |klass|
|
@@ -15,6 +16,20 @@ describe "Protocol Buffers" do
|
|
15
16
|
end
|
16
17
|
|
17
18
|
it_should_behave_like "Unified backend API"
|
19
|
+
|
20
|
+
describe "searching fulltext indexes (1.1 and earlier)", :version => '< 1.2.0' do
|
21
|
+
include_context "search corpus setup"
|
22
|
+
|
23
|
+
it 'should find document IDs via MapReduce' do
|
24
|
+
# Note that the trailing options Hash is ignored when
|
25
|
+
# emulating search with MapReduce
|
26
|
+
results = @backend.search 'search_test', 'fearless elephant rushed'
|
27
|
+
results.should have_key 'docs'
|
28
|
+
results.should have_key 'max_score'
|
29
|
+
results.should have_key 'num_found'
|
30
|
+
results['docs'].should include({"id" => "munchausen-605"})
|
31
|
+
end
|
32
|
+
end
|
18
33
|
end
|
19
34
|
end
|
20
35
|
end
|
@@ -61,8 +61,8 @@ describe "Multithreaded client", :test_server => true do
|
|
61
61
|
].each do |opts|
|
62
62
|
describe opts.inspect do
|
63
63
|
before do
|
64
|
-
@pb_port ||=
|
65
|
-
@http_port ||=
|
64
|
+
@pb_port ||= test_server.pb_port
|
65
|
+
@http_port ||= test_server.http_port
|
66
66
|
@client = Riak::Client.new({
|
67
67
|
:pb_port => @pb_port,
|
68
68
|
:http_port => @http_port
|
@@ -104,7 +104,7 @@ describe "Multithreaded client", :test_server => true do
|
|
104
104
|
# This is a 1.0+ spec because putting with the same client ID
|
105
105
|
# will not create siblings on 0.14 in the same way. This will
|
106
106
|
# also likely fail for nodes with vnode_vclocks = false.
|
107
|
-
it 'should put conflicts in parallel', :version => "1.0.0" do
|
107
|
+
it 'should put conflicts in parallel', :version => ">= 1.0.0" do
|
108
108
|
@client['test'].allow_mult = true
|
109
109
|
@client['test'].allow_mult.should == true
|
110
110
|
|
@@ -1,19 +1,17 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'riak/client/beefcake/messages'
|
3
2
|
|
4
3
|
describe Riak::Client::BeefcakeProtobuffsBackend do
|
5
|
-
before
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
4
|
+
before(:all) { described_class.should be_configured }
|
5
|
+
before(:each) { backend.stub(:get_server_version => "1.2.0") }
|
6
|
+
let(:client) { Riak::Client.new }
|
7
|
+
let(:node) { client.nodes.first }
|
8
|
+
let(:backend) { Riak::Client::BeefcakeProtobuffsBackend.new(client, node) }
|
11
9
|
|
12
10
|
it "should only write to the socket one time per request" do
|
13
11
|
exp_bucket, exp_keys = 'foo', ['bar']
|
14
12
|
mock_socket = mock("mock TCP socket")
|
15
13
|
|
16
|
-
|
14
|
+
backend.stub!(:socket).and_return(mock_socket)
|
17
15
|
mock_socket.should_receive(:write).exactly(1).with do |param|
|
18
16
|
len, code = param[0,5].unpack("NC")
|
19
17
|
req = Riak::Client::BeefcakeProtobuffsBackend::RpbListKeysReq.decode(param[5..-1])
|
@@ -36,27 +34,62 @@ describe Riak::Client::BeefcakeProtobuffsBackend do
|
|
36
34
|
mock_socket.should_receive(:read).exactly(1).with(encoded_response.length).and_return(encoded_response)
|
37
35
|
end
|
38
36
|
|
39
|
-
|
37
|
+
backend.list_keys(exp_bucket).should == exp_keys
|
40
38
|
end
|
41
|
-
end
|
42
39
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
40
|
+
context "#mapred" do
|
41
|
+
let(:mapred) { Riak::MapReduce.new(client).add('test').map("function(){}").map("function(){}") }
|
42
|
+
|
43
|
+
it "should not return nil for previous phases that don't return anything" do
|
44
|
+
socket = stub(:socket).as_null_object
|
45
|
+
socket.stub(:read).and_return(stub(:socket_header, :unpack => [2, 24]), stub(:socket_message), stub(:socket_header_2, :unpack => [0, 1]))
|
46
|
+
message = stub(:message, :phase => 1, :response => [{}].to_json)
|
47
|
+
message.stub(:done).and_return(false, true)
|
48
|
+
Riak::Client::BeefcakeProtobuffsBackend::RpbMapRedResp.stub(:decode => message)
|
49
|
+
TCPSocket.stub(:new => socket)
|
50
|
+
backend.send(:reset_socket)
|
51
|
+
|
52
|
+
backend.mapred(mapred).should == [{}]
|
53
|
+
end
|
49
54
|
end
|
50
55
|
|
51
|
-
|
52
|
-
|
53
|
-
socket.stub(:read).and_return(stub(:socket_header, :unpack => [2, 24]), stub(:socket_message), stub(:socket_header_2, :unpack => [0, 1]))
|
54
|
-
message = stub(:message, :phase => 1, :response => [{}].to_json)
|
55
|
-
message.stub(:done).and_return(false, true)
|
56
|
-
Riak::Client::BeefcakeProtobuffsBackend::RpbMapRedResp.stub(:decode => message)
|
57
|
-
TCPSocket.stub(:new => socket)
|
58
|
-
@backend.send(:reset_socket)
|
56
|
+
context "preventing stale writes" do
|
57
|
+
before { backend.stub(:decode_response => nil, :get_server_version => "1.0.3") }
|
59
58
|
|
60
|
-
|
59
|
+
let(:robject) do
|
60
|
+
Riak::RObject.new(client['stale'], 'prevent').tap do |obj|
|
61
|
+
obj.prevent_stale_writes = true
|
62
|
+
obj.raw_data = "stale"
|
63
|
+
obj.content_type = "text/plain"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should set the if_none_match field when the object is new" do
|
68
|
+
backend.should_receive(:write_protobuff) do |msg, req|
|
69
|
+
msg.should == :PutReq
|
70
|
+
req.if_none_match.should be_true
|
71
|
+
end
|
72
|
+
backend.store_object(robject)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should set the if_not_modified field when the object has a vclock" do
|
76
|
+
robject.vclock = Base64.encode64("foo")
|
77
|
+
backend.should_receive(:write_protobuff) do |msg, req|
|
78
|
+
msg.should == :PutReq
|
79
|
+
req.if_not_modified.should be_true
|
80
|
+
end
|
81
|
+
backend.store_object(robject)
|
82
|
+
end
|
83
|
+
|
84
|
+
context "when conditional requests are not supported" do
|
85
|
+
before { backend.stub(:get_server_version => "0.14.2") }
|
86
|
+
let(:other) { robject.dup.tap {|o| o.vclock = 'bar' } }
|
87
|
+
|
88
|
+
it "should fetch the original object and raise if not equivalent" do
|
89
|
+
robject.vclock = Base64.encode64("foo")
|
90
|
+
backend.should_receive(:fetch_object).and_return(other)
|
91
|
+
expect { backend.store_object(robject) }.to raise_error(Riak::FailedRequest)
|
92
|
+
end
|
93
|
+
end
|
61
94
|
end
|
62
95
|
end
|
data/spec/riak/escape_spec.rb
CHANGED
@@ -44,6 +44,7 @@ describe Riak::Util::Escape do
|
|
44
44
|
it "should escape standard non-safe characters" do
|
45
45
|
@object.escape("some string").should == "some%20string"
|
46
46
|
@object.escape("another^one").should == "another%5Eone"
|
47
|
+
@object.escape("--one+two--").should == "--one%2Btwo--"
|
47
48
|
end
|
48
49
|
|
49
50
|
it "should allow URI-safe characters" do
|
@@ -64,6 +65,8 @@ describe Riak::Util::Escape do
|
|
64
65
|
@object.unescape("another%5Eone").should == "another^one"
|
65
66
|
@object.unescape("bracket%5Bone").should == "bracket[one"
|
66
67
|
@object.unescape("some%2Finner%2Fpath").should == "some/inner/path"
|
68
|
+
@object.unescape("--one%2Btwo--").should == "--one+two--"
|
69
|
+
@object.unescape("me%40basho.co").should == "me@basho.co"
|
67
70
|
end
|
68
71
|
end
|
69
72
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'riak/client/feature_detection'
|
3
|
+
|
4
|
+
describe Riak::Client::FeatureDetection do
|
5
|
+
let(:klass) {
|
6
|
+
Class.new do
|
7
|
+
include Riak::Client::FeatureDetection
|
8
|
+
end
|
9
|
+
}
|
10
|
+
subject { klass.new }
|
11
|
+
|
12
|
+
context "when the get_server_version is unimplemented" do
|
13
|
+
it "should raise a NotImplementedError" do
|
14
|
+
expect { subject.server_version }.to raise_error(NotImplementedError)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when the Riak version is 0.14.x" do
|
19
|
+
before { subject.stub!(:get_server_version).and_return("0.14.2") }
|
20
|
+
it { should_not be_mapred_phaseless }
|
21
|
+
it { should_not be_pb_indexes }
|
22
|
+
it { should_not be_pb_search }
|
23
|
+
it { should_not be_pb_conditionals }
|
24
|
+
it { should_not be_quorum_controls }
|
25
|
+
it { should_not be_tombstone_vclocks }
|
26
|
+
it { should_not be_pb_head }
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when the Riak version is 1.0.x" do
|
30
|
+
before { subject.stub!(:get_server_version).and_return("1.0.3") }
|
31
|
+
it { should_not be_mapred_phaseless }
|
32
|
+
it { should_not be_pb_indexes }
|
33
|
+
it { should_not be_pb_search }
|
34
|
+
it { should be_pb_conditionals }
|
35
|
+
it { should be_quorum_controls }
|
36
|
+
it { should be_tombstone_vclocks }
|
37
|
+
it { should be_pb_head }
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when the Riak version is 1.1.x" do
|
41
|
+
before { subject.stub!(:get_server_version).and_return("1.1.4") }
|
42
|
+
it { should be_mapred_phaseless }
|
43
|
+
it { should_not be_pb_indexes }
|
44
|
+
it { should_not be_pb_search }
|
45
|
+
it { should be_pb_conditionals }
|
46
|
+
it { should be_quorum_controls }
|
47
|
+
it { should be_tombstone_vclocks }
|
48
|
+
it { should be_pb_head }
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when the Riak version is 1.2.x" do
|
52
|
+
before { subject.stub!(:get_server_version).and_return("1.2.0") }
|
53
|
+
it { should be_mapred_phaseless }
|
54
|
+
it { should be_pb_indexes }
|
55
|
+
it { should be_pb_search }
|
56
|
+
it { should be_pb_conditionals }
|
57
|
+
it { should be_quorum_controls }
|
58
|
+
it { should be_tombstone_vclocks }
|
59
|
+
it { should be_pb_head }
|
60
|
+
end
|
61
|
+
end
|
@@ -28,14 +28,13 @@ describe Riak::Client::HTTPBackend::ObjectMethods do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
it "should deserialize the body data" do
|
31
|
-
@object.should_receive(:deserialize).with("{}").and_return({})
|
32
31
|
@backend.load_object(@object, {:headers => {"content-type" => ["application/json"]}, :body => "{}"})
|
33
32
|
@object.data.should == {}
|
34
33
|
end
|
35
34
|
|
36
35
|
it "should leave the object data unchanged if the response body is blank" do
|
37
36
|
@object.data = "Original data"
|
38
|
-
@backend.load_object(@object, {:headers => {"content-type" => ["application/json"]}, :body => ""})
|
37
|
+
@backend.load_object(@object, {:headers => {"content-type" => ["application/json"]}, :body => "", :code => 304})
|
39
38
|
@object.data.should == "Original data"
|
40
39
|
end
|
41
40
|
|
@@ -84,7 +83,7 @@ describe Riak::Client::HTTPBackend::ObjectMethods do
|
|
84
83
|
end
|
85
84
|
|
86
85
|
context "when the response code is 300 and the content-type is multipart/mixed" do
|
87
|
-
let(:http_response) { {:headers => {"content-type" => ["multipart/mixed; boundary=
|
86
|
+
let(:http_response) { {:headers => {"content-type" => ["multipart/mixed; boundary=8XZD3w6ttFTHIz6LCmhVxn9Ex0K"]}, :code => 300, :body => File.read("spec/fixtures/multipart-basic-conflict.txt")} }
|
88
87
|
let(:other_object) { Riak::RObject.new(@bucket, "bar2") }
|
89
88
|
|
90
89
|
it 'marks the object as in conflict' do
|
@@ -106,22 +105,14 @@ describe Riak::Client::HTTPBackend::ObjectMethods do
|
|
106
105
|
|
107
106
|
describe "extracting siblings" do
|
108
107
|
before :each do
|
109
|
-
@backend.load_object(@object, {:headers => {"x-riak-vclock" => ["merged"], "content-type" => ["multipart/mixed; boundary=
|
108
|
+
@backend.load_object(@object, {:headers => {"x-riak-vclock" => ["merged"], "content-type" => ["multipart/mixed; boundary=8XZD3w6ttFTHIz6LCmhVxn9Ex0K"]}, :code => 300, :body => File.read("spec/fixtures/multipart-basic-conflict.txt")})
|
110
109
|
end
|
111
110
|
|
112
111
|
it "should extract the siblings" do
|
113
112
|
@object.should have(2).siblings
|
114
113
|
siblings = @object.siblings
|
115
114
|
siblings[0].data.should == "bar"
|
116
|
-
siblings[1].data.should == "
|
117
|
-
end
|
118
|
-
|
119
|
-
it "should set the key on both siblings" do
|
120
|
-
@object.siblings.should be_all {|s| s.key == "bar" }
|
121
|
-
end
|
122
|
-
|
123
|
-
it "should set the vclock on both siblings to the merged vclock" do
|
124
|
-
@object.siblings.should be_all {|s| s.vclock == "merged" }
|
115
|
+
siblings[1].data.should == "foo"
|
125
116
|
end
|
126
117
|
end
|
127
118
|
end
|
@@ -183,16 +183,17 @@ describe Riak::Client::HTTPBackend do
|
|
183
183
|
end
|
184
184
|
|
185
185
|
it "should issue POST request to the mapred endpoint" do
|
186
|
-
@backend.should_receive(:post).with(200, @backend.mapred_path, @mr.to_json, hash_including("Content-Type" => "application/json")).
|
186
|
+
@backend.should_receive(:post).with(200, @backend.mapred_path(:chunked => true), @mr.to_json, hash_including("Content-Type" => "application/json")).and_yield(%Q|--foo\r\nContent-Type: application/json\r\n\r\n{"phase":0,"data":[]}\r\n--foo--\r\n|)
|
187
187
|
@backend.mapred(@mr)
|
188
188
|
end
|
189
189
|
|
190
190
|
it "should vivify JSON responses" do
|
191
|
-
@backend.stub!(:post).
|
191
|
+
@backend.stub!(:post).and_yield(%Q|--foo\r\nContent-Type: application/json\r\n\r\n{"phase":0,"data":[{"key":"value"}]}\r\n--foo--\r\n|)
|
192
192
|
@backend.mapred(@mr).should == [{"key" => "value"}]
|
193
193
|
end
|
194
194
|
|
195
195
|
it "should return the full response hash for non-JSON responses" do
|
196
|
+
pending "It is not clear when Riak would ever return a non-JSON or non-multipart response for mapred."
|
196
197
|
response = {:code => 200, :headers => {'content-type' => ["text/plain"]}, :body => 'This is some text.'}
|
197
198
|
@backend.stub!(:post).and_return(response)
|
198
199
|
@backend.mapred(@mr).should == response
|
@@ -272,9 +273,9 @@ describe Riak::Client::HTTPBackend do
|
|
272
273
|
@backend.search(nil, 'foo')
|
273
274
|
end
|
274
275
|
|
275
|
-
it "should vivify JSON responses" do
|
276
|
-
@backend.should_receive(:get).and_return({:code => 200, :headers => {"content-type"=>["application/json"]}, :body => '{"response":{"docs":["foo"]}}'})
|
277
|
-
@backend.search(nil, "foo").should == {"
|
276
|
+
it "should vivify and normalize JSON responses" do
|
277
|
+
@backend.should_receive(:get).and_return({:code => 200, :headers => {"content-type"=>["application/json"]}, :body => '{"response":{"docs":[{"id":"foo","fields":{},"props":{}}],"maxScore":"0.0345","numFound":1}}'})
|
278
|
+
@backend.search(nil, "foo").should == {"docs" => [{"id" => "foo"}], "max_score" => 0.0345, "num_found" => 1}
|
278
279
|
end
|
279
280
|
|
280
281
|
it "should return non-JSON responses raw" do
|
@@ -330,11 +330,6 @@ describe Riak::MapReduce do
|
|
330
330
|
@mr.map("Riak.mapValues",:keep => true)
|
331
331
|
end
|
332
332
|
|
333
|
-
it "should raise an exception when no phases are defined" do
|
334
|
-
@mr.query.clear
|
335
|
-
lambda { @mr.run }.should raise_error(Riak::MapReduceError)
|
336
|
-
end
|
337
|
-
|
338
333
|
it "should submit the query to the backend" do
|
339
334
|
@backend.should_receive(:mapred).with(@mr).and_return([])
|
340
335
|
@mr.run.should == []
|
data/spec/riak/robject_spec.rb
CHANGED
@@ -50,14 +50,14 @@ describe Riak::RObject do
|
|
50
50
|
@object.content_type = 'text/plain'
|
51
51
|
Riak::Serializers.should respond_to(:serialize).with(2).arguments
|
52
52
|
Riak::Serializers.should_receive(:serialize).with('text/plain', "foo").and_return("serialized foo")
|
53
|
-
@object.serialize("foo").should == "serialized foo"
|
53
|
+
@object.content.serialize("foo").should == "serialized foo"
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'delegates #deserialize to the appropriate serializer for the content type' do
|
57
57
|
@object.content_type = 'text/plain'
|
58
58
|
Riak::Serializers.should respond_to(:deserialize).with(2).arguments
|
59
59
|
Riak::Serializers.should_receive(:deserialize).with('text/plain', "foo").and_return("deserialized foo")
|
60
|
-
@object.deserialize("foo").should == "deserialized foo"
|
60
|
+
@object.content.deserialize("foo").should == "deserialized foo"
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -113,7 +113,7 @@ describe Riak::RObject do
|
|
113
113
|
let(:io_object) { stub(:read => 'the io object') }
|
114
114
|
|
115
115
|
it 'reads the object before deserializing it' do
|
116
|
-
@object.should_receive(:deserialize).with('the io object').and_return('deserialized')
|
116
|
+
@object.content.should_receive(:deserialize).with('the io object').and_return('deserialized')
|
117
117
|
@object.raw_data = io_object
|
118
118
|
@object.data.should == 'deserialized'
|
119
119
|
end
|
@@ -214,8 +214,8 @@ describe Riak::RObject do
|
|
214
214
|
@object.conflict?.should be_false
|
215
215
|
end
|
216
216
|
|
217
|
-
it 'should return [
|
218
|
-
@object.siblings.should == [@object]
|
217
|
+
it 'should return [RContent] for siblings' do
|
218
|
+
@object.siblings.should == [@object.content]
|
219
219
|
end
|
220
220
|
|
221
221
|
describe "when there are multiple values in an object" do
|
@@ -241,13 +241,9 @@ describe Riak::RObject do
|
|
241
241
|
end
|
242
242
|
|
243
243
|
it "should be in conflict" do
|
244
|
-
@object.data.
|
244
|
+
expect { @object.data }.to raise_error(Riak::Conflict)
|
245
245
|
@object.should be_conflict
|
246
246
|
end
|
247
|
-
|
248
|
-
it "should assign the same vclock to all the siblings" do
|
249
|
-
@object.siblings.should be_all {|s| s.vclock == @object.vclock }
|
250
|
-
end
|
251
247
|
end
|
252
248
|
end
|
253
249
|
|
@@ -285,6 +281,11 @@ describe Riak::RObject do
|
|
285
281
|
@backend.should_receive(:store_object).with(@object, :returnbody => false, :w => 3, :dw => 2).and_return(true)
|
286
282
|
@object.store(:returnbody => false, :w => 3, :dw => 2)
|
287
283
|
end
|
284
|
+
|
285
|
+
it "should raise an error if the object is in conflict" do
|
286
|
+
@object.siblings << Riak::RContent.new(@object)
|
287
|
+
expect { @object.store }.to raise_error(Riak::Conflict)
|
288
|
+
end
|
288
289
|
end
|
289
290
|
|
290
291
|
describe "when reloading the object" do
|
@@ -419,7 +420,7 @@ describe Riak::RObject do
|
|
419
420
|
end
|
420
421
|
|
421
422
|
describe '#attempt_conflict_resolution' do
|
422
|
-
let(:conflicted_robject) { Riak::RObject.new(@bucket, "conflicted") { |r| r.
|
423
|
+
let(:conflicted_robject) { Riak::RObject.new(@bucket, "conflicted") { |r| r.siblings = [ Riak::RContent.new(r), Riak::RContent.new(r)] } }
|
423
424
|
let(:resolved_robject) { Riak::RObject.new(@bucket, "resolved") }
|
424
425
|
let(:invoked_resolvers) { [] }
|
425
426
|
let(:resolver_1) { lambda { |r| invoked_resolvers << :resolver_1; nil } }
|