riak-client 1.0.5 → 1.1.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.
- 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 } }
|