riak-client 0.7.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/Rakefile +74 -0
- data/lib/riak.rb +49 -0
- data/lib/riak/bucket.rb +176 -0
- data/lib/riak/cache_store.rb +82 -0
- data/lib/riak/client.rb +139 -0
- data/lib/riak/client/curb_backend.rb +82 -0
- data/lib/riak/client/http_backend.rb +209 -0
- data/lib/riak/client/net_http_backend.rb +49 -0
- data/lib/riak/failed_request.rb +37 -0
- data/lib/riak/i18n.rb +20 -0
- data/lib/riak/invalid_response.rb +25 -0
- data/lib/riak/link.rb +73 -0
- data/lib/riak/locale/en.yml +37 -0
- data/lib/riak/map_reduce.rb +248 -0
- data/lib/riak/map_reduce_error.rb +20 -0
- data/lib/riak/robject.rb +267 -0
- data/lib/riak/util/escape.rb +12 -0
- data/lib/riak/util/fiber1.8.rb +48 -0
- data/lib/riak/util/headers.rb +44 -0
- data/lib/riak/util/multipart.rb +52 -0
- data/lib/riak/util/translation.rb +29 -0
- data/lib/riak/walk_spec.rb +117 -0
- data/spec/fixtures/cat.jpg +0 -0
- data/spec/fixtures/multipart-blank.txt +7 -0
- data/spec/fixtures/multipart-with-body.txt +16 -0
- data/spec/integration/riak/cache_store_spec.rb +129 -0
- data/spec/riak/bucket_spec.rb +247 -0
- data/spec/riak/client_spec.rb +174 -0
- data/spec/riak/curb_backend_spec.rb +53 -0
- data/spec/riak/escape_spec.rb +21 -0
- data/spec/riak/headers_spec.rb +34 -0
- data/spec/riak/http_backend_spec.rb +131 -0
- data/spec/riak/link_spec.rb +82 -0
- data/spec/riak/map_reduce_spec.rb +352 -0
- data/spec/riak/multipart_spec.rb +36 -0
- data/spec/riak/net_http_backend_spec.rb +28 -0
- data/spec/riak/object_spec.rb +538 -0
- data/spec/riak/walk_spec_spec.rb +208 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/support/http_backend_implementation_examples.rb +215 -0
- data/spec/support/mock_server.rb +61 -0
- data/spec/support/mocks.rb +3 -0
- metadata +187 -0
@@ -0,0 +1,247 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
15
|
+
|
16
|
+
describe Riak::Bucket do
|
17
|
+
before :each do
|
18
|
+
@client = Riak::Client.new
|
19
|
+
@bucket = Riak::Bucket.new(@client, "foo")
|
20
|
+
end
|
21
|
+
|
22
|
+
def do_load(overrides={})
|
23
|
+
@bucket.load({
|
24
|
+
:body => '{"props":{"name":"foo","allow_mult":false,"big_vclock":50,"chash_keyfun":{"mod":"riak_util","fun":"chash_std_keyfun"},"linkfun":{"mod":"jiak_object","fun":"mapreduce_linkfun"},"n_val":3,"old_vclock":86400,"small_vclock":10,"young_vclock":20},"keys":["bar"]}',
|
25
|
+
:headers => {
|
26
|
+
"vary" => ["Accept-Encoding"],
|
27
|
+
"server" => ["MochiWeb/1.1 WebMachine/1.5.1 (hack the charles gibson)"],
|
28
|
+
"link" => ['</riak/foo/bar>; riaktag="contained"'],
|
29
|
+
"date" => ["Tue, 12 Jan 2010 15:30:43 GMT"],
|
30
|
+
"content-type" => ["application/json"],
|
31
|
+
"content-length" => ["257"]
|
32
|
+
}
|
33
|
+
}.merge(overrides))
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
describe "when initializing" do
|
38
|
+
it "should require a client and a name" do
|
39
|
+
lambda { Riak::Bucket.new }.should raise_error
|
40
|
+
lambda { Riak::Bucket.new(@client) }.should raise_error
|
41
|
+
lambda { Riak::Bucket.new("foo") }.should raise_error
|
42
|
+
lambda { Riak::Bucket.new("foo", @client) }.should raise_error
|
43
|
+
lambda { Riak::Bucket.new(@client, "foo") }.should_not raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should set the client and name attributes" do
|
47
|
+
bucket = Riak::Bucket.new(@client, "foo")
|
48
|
+
bucket.client.should == @client
|
49
|
+
bucket.name.should == "foo"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "when loading data from an HTTP response" do
|
54
|
+
it "should load the bucket properties from the response body" do
|
55
|
+
do_load
|
56
|
+
@bucket.props.should == {"name"=>"foo","allow_mult" => false,"big_vclock" => 50,"chash_keyfun" => {"mod" =>"riak_util","fun"=>"chash_std_keyfun"},"linkfun"=>{"mod"=>"jiak_object","fun"=>"mapreduce_linkfun"},"n_val"=>3,"old_vclock"=>86400,"small_vclock"=>10,"young_vclock"=>20}
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should load the keys from the response body" do
|
60
|
+
do_load
|
61
|
+
@bucket.keys.should == ["bar"]
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should raise an error for a response that is not JSON" do
|
65
|
+
lambda do
|
66
|
+
do_load(:headers => {"content-type" => ["text/plain"]})
|
67
|
+
end.should raise_error(Riak::InvalidResponse)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should unescape key names" do
|
71
|
+
do_load(:body => '{"keys":["foo", "bar%20baz"]}')
|
72
|
+
@bucket.keys.should == ["foo", "bar baz"]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "accessing keys" do
|
77
|
+
before :each do
|
78
|
+
@http = mock("HTTPBackend")
|
79
|
+
@client.stub!(:http).and_return(@http)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should load the keys if not present" do
|
83
|
+
@http.should_receive(:get).with(200, "/riak/", "foo", {:props => false}, {}).and_return({:headers => {"content-type" => ["application/json"]}, :body => '{"keys":["bar"]}'})
|
84
|
+
@bucket.keys.should == ["bar"]
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should allow reloading of the keys" do
|
88
|
+
@http.should_receive(:get).with(200, "/riak/","foo", {:props => false}, {}).and_return({:headers => {"content-type" => ["application/json"]}, :body => '{"keys":["bar"]}'})
|
89
|
+
do_load # Ensures they're already loaded
|
90
|
+
@bucket.keys(:reload => true).should == ["bar"]
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should allow streaming keys through block" do
|
94
|
+
# pending "Needs support in the raw_http_resource"
|
95
|
+
@http.should_receive(:get).with(200, "/riak/","foo", {:props => false, :keys => "stream"}, {}).and_yield("{}").and_yield('{"keys":[]}').and_yield('{"keys":["bar"]}').and_yield('{"keys":["baz"]}')
|
96
|
+
all_keys = []
|
97
|
+
@bucket.keys do |list|
|
98
|
+
all_keys.concat(list)
|
99
|
+
end
|
100
|
+
all_keys.should == ["bar", "baz"]
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should unescape key names" do
|
104
|
+
@http.should_receive(:get).with(200, "/riak/","foo", {:props => false}, {}).and_return({:headers => {"content-type" => ["application/json"]}, :body => '{"keys":["bar%20baz"]}'})
|
105
|
+
@bucket.keys.should == ["bar baz"]
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should escape the bucket name" do
|
109
|
+
@bucket.instance_variable_set :@name, "unescaped "
|
110
|
+
@http.should_receive(:get).with(200, "/riak/","unescaped%20", {:props => false}, {}).and_return({:headers => {"content-type" => ["application/json"]}, :body => '{"keys":["bar"]}'})
|
111
|
+
@bucket.keys.should == ["bar"]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "setting the bucket properties" do
|
116
|
+
before :each do
|
117
|
+
@http = mock("HTTPBackend")
|
118
|
+
@client.stub!(:http).and_return(@http)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should PUT the new properties to the bucket" do
|
122
|
+
@http.should_receive(:put).with(204, "/riak/","foo", '{"props":{"name":"foo"}}', {"Content-Type" => "application/json"}).and_return({:body => "", :headers => {}})
|
123
|
+
@bucket.props = { :name => "foo" }
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should raise an error if an invalid property is given" do
|
127
|
+
lambda { @bucket.props = "blah" }.should raise_error(ArgumentError)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should escape the bucket name" do
|
131
|
+
@bucket.instance_variable_set :@name, "foo bar"
|
132
|
+
@http.should_receive(:put).with(204, "/riak/","foo%20bar", '{"props":{"n_val":2}}', {"Content-Type" => "application/json"}).and_return({:body => "", :headers => {}})
|
133
|
+
@bucket.props = {:n_val => 2}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "fetching an object" do
|
138
|
+
before :each do
|
139
|
+
@http = mock("HTTPBackend")
|
140
|
+
@client.stub!(:http).and_return(@http)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should load the object from the server as a Riak::RObject" do
|
144
|
+
@http.should_receive(:get).with(200, "/riak/","foo", "db", {}, {}).and_return({:headers => {"content-type" => ["application/json"]}, :body => '{"name":"Riak","company":"Basho"}'})
|
145
|
+
@bucket.get("db").should be_kind_of(Riak::RObject)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should use the given query parameters (for R value, etc)" do
|
149
|
+
@http.should_receive(:get).with(200, "/riak/","foo", "db", {:r => 2}, {}).and_return({:headers => {"content-type" => ["application/json"]}, :body => '{"name":"Riak","company":"Basho"}'})
|
150
|
+
@bucket.get("db", :r => 2).should be_kind_of(Riak::RObject)
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should allow 300 responses if allow_mult is set" do
|
154
|
+
@bucket.instance_variable_set(:@props, {'allow_mult' => true})
|
155
|
+
@http.should_receive(:get).with([200,300], "/riak/","foo", "db", {}, {}).and_return({:headers => {"content-type" => ["application/json"]}, :body => '{"name":"Riak","company":"Basho"}'})
|
156
|
+
@bucket.get('db')
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should escape the bucket and key names" do
|
160
|
+
@bucket.instance_variable_set(:@name, "foo ")
|
161
|
+
@http.should_receive(:get).with(200, "/riak/","foo%20", "%20bar", {}, {}).and_return({:headers => {"content-type" => ["application/json"]}, :body => '{"name":"Riak","company":"Basho"}'})
|
162
|
+
@bucket.get(' bar')
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "creating a new blank object" do
|
167
|
+
it "should instantiate the object with the given key, default to JSON" do
|
168
|
+
obj = @bucket.new('bar')
|
169
|
+
obj.should be_kind_of(Riak::RObject)
|
170
|
+
obj.key.should == 'bar'
|
171
|
+
obj.content_type.should == 'application/json'
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "fetching or creating a new object" do
|
176
|
+
before :each do
|
177
|
+
@http = mock("HTTPBackend")
|
178
|
+
@client.stub!(:http).and_return(@http)
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should return the existing object if present" do
|
182
|
+
@http.should_receive(:get).with(200, "/riak/","foo", "db", {}, {}).and_return({:headers => {"content-type" => ["application/json"]}, :body => '{"name":"Riak","company":"Basho"}'})
|
183
|
+
obj = @bucket.get_or_new('db')
|
184
|
+
obj.key.should == 'db'
|
185
|
+
obj.data['name'].should == "Riak"
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should create a new blank object if the key does not exist" do
|
189
|
+
@http.should_receive(:get).and_raise(Riak::FailedRequest.new(:get, 200, 404, {}, "File not found"))
|
190
|
+
obj = @bucket.get_or_new('db')
|
191
|
+
obj.key.should == 'db'
|
192
|
+
obj.data.should be_blank
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should bubble up non-ok non-missing errors" do
|
196
|
+
@http.should_receive(:get).and_raise(Riak::FailedRequest.new(:get, 200, 500, {}, "File not found"))
|
197
|
+
lambda { @bucket.get_or_new('db') }.should raise_error(Riak::FailedRequest)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "get/set allow_mult property" do
|
202
|
+
before :each do
|
203
|
+
do_load
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should extract the allow_mult property" do
|
207
|
+
@bucket.allow_mult.should be_false
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should set the allow_mult property" do
|
211
|
+
@bucket.should_receive(:props=).with(hash_including('allow_mult' => true))
|
212
|
+
@bucket.allow_mult = true
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe "get/set the N value" do
|
217
|
+
before :each do
|
218
|
+
do_load
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should extract the N value" do
|
222
|
+
@bucket.n_value.should == 3
|
223
|
+
end
|
224
|
+
|
225
|
+
it "should set the N value" do
|
226
|
+
@bucket.should_receive(:props=).with(hash_including('n_val' => 1))
|
227
|
+
@bucket.n_value = 1
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "checking whether a key exists" do
|
232
|
+
it "should return true if the object does exist" do
|
233
|
+
@client.http.should_receive(:head).and_return(:code => 200)
|
234
|
+
@bucket.exists?("foo").should be_true
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should return false if the object doesn't exist" do
|
238
|
+
@client.http.should_receive(:head).and_return(:code => 404)
|
239
|
+
@bucket.exists?("foo").should be_false
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should delete a key from within the bucket" do
|
244
|
+
@client.http.should_receive(:delete).with([204,404], @client.prefix, @bucket.name, 'bar',{},{}).and_return(:code => 204)
|
245
|
+
@bucket.delete('bar')
|
246
|
+
end
|
247
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
15
|
+
|
16
|
+
describe Riak::Client do
|
17
|
+
describe "when initializing" do
|
18
|
+
it "should default to the local interface on port 8098" do
|
19
|
+
client = Riak::Client.new
|
20
|
+
client.host.should == "127.0.0.1"
|
21
|
+
client.port.should == 8098
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should accept a host" do
|
25
|
+
client = Riak::Client.new :host => "riak.basho.com"
|
26
|
+
client.host.should == "riak.basho.com"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should accept a port" do
|
30
|
+
client = Riak::Client.new :port => 9000
|
31
|
+
client.port.should == 9000
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should accept a client ID" do
|
35
|
+
client = Riak::Client.new :client_id => "AAAAAA=="
|
36
|
+
client.client_id.should == "AAAAAA=="
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should turn an integer client ID into a base64-encoded string" do
|
40
|
+
client = Riak::Client.new :client_id => 1
|
41
|
+
client.client_id.should == "AAAAAQ=="
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should create a client ID if not specified" do
|
45
|
+
Riak::Client.new.client_id.should be_kind_of(String)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should accept a path prefix" do
|
49
|
+
client = Riak::Client.new(:prefix => "/jiak/")
|
50
|
+
client.prefix.should == "/jiak/"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should default the prefix to /riak/ if not specified" do
|
54
|
+
Riak::Client.new.prefix.should == "/riak/"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should accept a mapreduce path" do
|
58
|
+
client = Riak::Client.new(:mapred => "/mr")
|
59
|
+
client.mapred.should == "/mr"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should default the mapreduce path to /mapred if not specified" do
|
63
|
+
Riak::Client.new.mapred.should == "/mapred"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "reconfiguring" do
|
68
|
+
before :each do
|
69
|
+
@client = Riak::Client.new
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "setting the host" do
|
73
|
+
it "should allow setting the host" do
|
74
|
+
@client.should respond_to(:host=)
|
75
|
+
@client.host = "riak.basho.com"
|
76
|
+
@client.host.should == "riak.basho.com"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should require the host to be an IP or hostname" do
|
80
|
+
[238472384972, ""].each do |invalid|
|
81
|
+
lambda { @client.host = invalid }.should raise_error(ArgumentError)
|
82
|
+
end
|
83
|
+
["127.0.0.1", "10.0.100.5", "localhost", "otherhost.local", "riak.basho.com"].each do |valid|
|
84
|
+
lambda { @client.host = valid }.should_not raise_error
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "setting the port" do
|
90
|
+
it "should allow setting the port" do
|
91
|
+
@client.should respond_to(:port=)
|
92
|
+
@client.port = 9000
|
93
|
+
@client.port.should == 9000
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should require the port to be a valid number" do
|
97
|
+
[-1,65536,"foo"].each do |invalid|
|
98
|
+
lambda { @client.port = invalid }.should raise_error(ArgumentError)
|
99
|
+
end
|
100
|
+
[0,1,65535,8098].each do |valid|
|
101
|
+
lambda { @client.port = valid }.should_not raise_error
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should allow setting the prefix (although we prefer the raw interface)" do
|
107
|
+
@client.should respond_to(:prefix=)
|
108
|
+
@client.prefix = "/another-prefix"
|
109
|
+
@client.prefix.should == "/another-prefix"
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "setting the client id" do
|
113
|
+
it "should accept a string unmodified" do
|
114
|
+
@client.client_id = "foo"
|
115
|
+
@client.client_id.should == "foo"
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should base64-encode an integer" do
|
119
|
+
@client.client_id = 1
|
120
|
+
@client.client_id.should == "AAAAAQ=="
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should reject an integer equal to the maximum client id" do
|
124
|
+
lambda { @client.client_id = Riak::Client::MAX_CLIENT_ID }.should raise_error(ArgumentError)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should reject an integer larger than the maximum client id" do
|
128
|
+
lambda { @client.client_id = Riak::Client::MAX_CLIENT_ID + 1 }.should raise_error(ArgumentError)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "choosing an HTTP backend" do
|
134
|
+
before :each do
|
135
|
+
@client = Riak::Client.new
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should choose the Curb backend if Curb is available" do
|
139
|
+
@client.should_receive(:require).with('curb').and_return(true)
|
140
|
+
@client.http.should be_instance_of(Riak::Client::CurbBackend)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should choose the Net::HTTP backend if Curb is unavailable" do
|
144
|
+
@client.should_receive(:require).with('curb').and_raise(LoadError)
|
145
|
+
@client.should_receive(:warn).and_return(true)
|
146
|
+
@client.http.should be_instance_of(Riak::Client::NetHTTPBackend)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "retrieving a bucket" do
|
151
|
+
before :each do
|
152
|
+
@client = Riak::Client.new
|
153
|
+
@http = mock(Riak::Client::HTTPBackend)
|
154
|
+
@client.stub!(:http).and_return(@http)
|
155
|
+
@payload = {:headers => {"content-type" => ["application/json"]}, :body => "{}"}
|
156
|
+
@http.stub!(:get).and_return(@payload)
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should send a GET request to the bucket name and return a Riak::Bucket" do
|
160
|
+
@http.should_receive(:get).with(200, "/riak/", "foo", {}, {}).and_return(@payload)
|
161
|
+
@client.bucket("foo").should be_kind_of(Riak::Bucket)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should allow requesting bucket properties without the keys" do
|
165
|
+
@http.should_receive(:get).with(200, "/riak/", "foo", {:keys => false}, {}).and_return(@payload)
|
166
|
+
@client.bucket("foo", :keys => false)
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should escape bucket names with invalid characters" do
|
170
|
+
@http.should_receive(:get).with(200, "/riak/", "foo%2Fbar%20", {:keys => false}, {}).and_return(@payload)
|
171
|
+
@client.bucket("foo/bar ", :keys => false)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
15
|
+
|
16
|
+
begin
|
17
|
+
require 'curb'
|
18
|
+
rescue LoadError
|
19
|
+
warn "Skipping CurbBackend specs, curb library not found."
|
20
|
+
else
|
21
|
+
$server = MockServer.new
|
22
|
+
at_exit { $server.stop }
|
23
|
+
|
24
|
+
describe Riak::Client::CurbBackend do
|
25
|
+
def setup_http_mock(method, uri, options={})
|
26
|
+
method = method.to_s.upcase
|
27
|
+
uri = URI.parse(uri)
|
28
|
+
path = uri.path || "/"
|
29
|
+
query = uri.query || ""
|
30
|
+
status = options[:status] ? Array(options[:status]).first.to_i : 200
|
31
|
+
body = options[:body] || []
|
32
|
+
headers = options[:headers] || {}
|
33
|
+
headers['Content-Type'] ||= "text/plain"
|
34
|
+
$server.attach do |env|
|
35
|
+
env["REQUEST_METHOD"].should == method
|
36
|
+
env["PATH_INFO"].should == path
|
37
|
+
env["QUERY_STRING"].should == query
|
38
|
+
[status, headers, Array(body)]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
before :each do
|
43
|
+
@client = Riak::Client.new(:port => $server.port) # Point to our mock
|
44
|
+
@backend = Riak::Client::CurbBackend.new(@client)
|
45
|
+
end
|
46
|
+
|
47
|
+
it_should_behave_like "HTTP backend"
|
48
|
+
|
49
|
+
after :each do
|
50
|
+
$server.detach
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|