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.
Files changed (43) hide show
  1. data/Rakefile +74 -0
  2. data/lib/riak.rb +49 -0
  3. data/lib/riak/bucket.rb +176 -0
  4. data/lib/riak/cache_store.rb +82 -0
  5. data/lib/riak/client.rb +139 -0
  6. data/lib/riak/client/curb_backend.rb +82 -0
  7. data/lib/riak/client/http_backend.rb +209 -0
  8. data/lib/riak/client/net_http_backend.rb +49 -0
  9. data/lib/riak/failed_request.rb +37 -0
  10. data/lib/riak/i18n.rb +20 -0
  11. data/lib/riak/invalid_response.rb +25 -0
  12. data/lib/riak/link.rb +73 -0
  13. data/lib/riak/locale/en.yml +37 -0
  14. data/lib/riak/map_reduce.rb +248 -0
  15. data/lib/riak/map_reduce_error.rb +20 -0
  16. data/lib/riak/robject.rb +267 -0
  17. data/lib/riak/util/escape.rb +12 -0
  18. data/lib/riak/util/fiber1.8.rb +48 -0
  19. data/lib/riak/util/headers.rb +44 -0
  20. data/lib/riak/util/multipart.rb +52 -0
  21. data/lib/riak/util/translation.rb +29 -0
  22. data/lib/riak/walk_spec.rb +117 -0
  23. data/spec/fixtures/cat.jpg +0 -0
  24. data/spec/fixtures/multipart-blank.txt +7 -0
  25. data/spec/fixtures/multipart-with-body.txt +16 -0
  26. data/spec/integration/riak/cache_store_spec.rb +129 -0
  27. data/spec/riak/bucket_spec.rb +247 -0
  28. data/spec/riak/client_spec.rb +174 -0
  29. data/spec/riak/curb_backend_spec.rb +53 -0
  30. data/spec/riak/escape_spec.rb +21 -0
  31. data/spec/riak/headers_spec.rb +34 -0
  32. data/spec/riak/http_backend_spec.rb +131 -0
  33. data/spec/riak/link_spec.rb +82 -0
  34. data/spec/riak/map_reduce_spec.rb +352 -0
  35. data/spec/riak/multipart_spec.rb +36 -0
  36. data/spec/riak/net_http_backend_spec.rb +28 -0
  37. data/spec/riak/object_spec.rb +538 -0
  38. data/spec/riak/walk_spec_spec.rb +208 -0
  39. data/spec/spec_helper.rb +30 -0
  40. data/spec/support/http_backend_implementation_examples.rb +215 -0
  41. data/spec/support/mock_server.rb +61 -0
  42. data/spec/support/mocks.rb +3 -0
  43. metadata +187 -0
@@ -0,0 +1,208 @@
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::WalkSpec do
17
+ describe "initializing" do
18
+ describe "with a hash" do
19
+ it "should be empty by default" do
20
+ spec = Riak::WalkSpec.new({})
21
+ spec.bucket.should == "_"
22
+ spec.tag.should == "_"
23
+ spec.keep.should be_false
24
+ end
25
+
26
+ it "should extract the bucket" do
27
+ spec = Riak::WalkSpec.new({:bucket => "foo"})
28
+ spec.bucket.should == "foo"
29
+ spec.tag.should == "_"
30
+ spec.keep.should be_false
31
+ end
32
+
33
+ it "should extract the tag" do
34
+ spec = Riak::WalkSpec.new({:tag => "foo"})
35
+ spec.bucket.should == "_"
36
+ spec.tag.should == "foo"
37
+ spec.keep.should be_false
38
+ end
39
+
40
+ it "should extract the keep" do
41
+ spec = Riak::WalkSpec.new({:keep => true})
42
+ spec.bucket.should == "_"
43
+ spec.tag.should == "_"
44
+ spec.keep.should be_true
45
+ end
46
+ end
47
+
48
+ describe "with three arguments for bucket, tag, and keep" do
49
+ it "should assign the bucket, tag, and keep" do
50
+ spec = Riak::WalkSpec.new("foo", "next", false)
51
+ spec.bucket.should == "foo"
52
+ spec.tag.should == "next"
53
+ spec.keep.should be_false
54
+ end
55
+
56
+ it "should make the bucket '_' when false or nil" do
57
+ spec = Riak::WalkSpec.new(nil, "next", false)
58
+ spec.bucket.should == "_"
59
+ spec = Riak::WalkSpec.new(false, "next", false)
60
+ spec.bucket.should == "_"
61
+ end
62
+
63
+ it "should make the tag '_' when false or nil" do
64
+ spec = Riak::WalkSpec.new("foo", nil, false)
65
+ spec.tag.should == "_"
66
+ spec = Riak::WalkSpec.new("foo", false, false)
67
+ spec.tag.should == "_"
68
+ end
69
+
70
+ it "should make the keep false when false or nil" do
71
+ spec = Riak::WalkSpec.new(nil, nil, nil)
72
+ spec.keep.should be_false
73
+ spec = Riak::WalkSpec.new(nil, nil, false)
74
+ spec.keep.should be_false
75
+ end
76
+ end
77
+
78
+ it "should raise an ArgumentError for invalid arguments" do
79
+ lambda { Riak::WalkSpec.new }.should raise_error(ArgumentError)
80
+ lambda { Riak::WalkSpec.new("foo") }.should raise_error(ArgumentError)
81
+ lambda { Riak::WalkSpec.new("foo","bar") }.should raise_error(ArgumentError)
82
+ end
83
+ end
84
+
85
+ describe "converting to a string" do
86
+ before :each do
87
+ @spec = Riak::WalkSpec.new({})
88
+ end
89
+
90
+ it "should be the empty spec by default" do
91
+ @spec.to_s.should == "_,_,_"
92
+ end
93
+
94
+ it "should include the bucket when set" do
95
+ @spec.bucket = "foo"
96
+ @spec.to_s.should == "foo,_,_"
97
+ end
98
+
99
+ it "should include the tag when set" do
100
+ @spec.tag = "next"
101
+ @spec.to_s.should == "_,next,_"
102
+ end
103
+
104
+ it "should include the keep when true" do
105
+ @spec.keep = true
106
+ @spec.to_s.should == "_,_,1"
107
+ end
108
+ end
109
+
110
+ describe "creating from a list of parameters" do
111
+ it "should detect hashes and WalkSpecs interleaved with other parameters" do
112
+ specs = Riak::WalkSpec.normalize(nil,"next",nil,{:bucket => "foo"},Riak::WalkSpec.new({:tag => "child", :keep => true}))
113
+ specs.should have(3).items
114
+ specs.should be_all {|s| s.kind_of?(Riak::WalkSpec) }
115
+ specs.join("/").should == "_,next,_/foo,_,_/_,child,1"
116
+ end
117
+ end
118
+
119
+ describe "matching other objects with ===" do
120
+ before :each do
121
+ @spec = Riak::WalkSpec.new({})
122
+ end
123
+
124
+ it "should not match objects that aren't links or walk specs" do
125
+ @spec.should_not === "foo"
126
+ end
127
+
128
+ describe "matching links" do
129
+ before :each do
130
+ @link = Riak::Link.new("/riak/foo/bar", "next")
131
+ end
132
+
133
+ it "should match a link when the bucket and tag are not specified" do
134
+ @spec.should === @link
135
+ end
136
+
137
+ it "should match a link when the bucket is the same" do
138
+ @spec.bucket = "foo"
139
+ @spec.should === @link
140
+ end
141
+
142
+ it "should not match a link when the bucket is different" do
143
+ @spec.bucket = "bar"
144
+ @spec.should_not === @link
145
+ end
146
+
147
+ it "should match a link when the tag is the same" do
148
+ @spec.tag = "next"
149
+ @spec.should === @link
150
+ end
151
+
152
+ it "should not match a link when the tag is different" do
153
+ @spec.tag = "previous"
154
+ @spec.should_not === @link
155
+ end
156
+
157
+ it "should match a link when the bucket and tag are the same" do
158
+ @spec.bucket = "foo"
159
+ @spec.should === @link
160
+ end
161
+ end
162
+
163
+ describe "matching walk specs" do
164
+ before :each do
165
+ @other = Riak::WalkSpec.new({})
166
+ end
167
+
168
+ it "should match a walk spec that is equivalent" do
169
+ @spec.should === @other
170
+ end
171
+
172
+ it "should not match a walk spec that has a different keep value" do
173
+ @other.keep = true
174
+ @spec.should_not === @other
175
+ end
176
+
177
+ it "should match a walk spec with a more specific bucket" do
178
+ @other.bucket = "foo"
179
+ @spec.should === @other
180
+ end
181
+
182
+ it "should match a walk spec with the same bucket" do
183
+ @other.bucket = "foo"; @spec.bucket = "foo"
184
+ @spec.should === @other
185
+ end
186
+
187
+ it "should not match a walk spec with a different bucket" do
188
+ @other.bucket = "foo"; @spec.bucket = "bar"
189
+ @spec.should_not === @other
190
+ end
191
+
192
+ it "should match a walk spec with a more specific tag" do
193
+ @other.tag = "next"
194
+ @spec.should === @other
195
+ end
196
+
197
+ it "should match a walk spec with the same tag" do
198
+ @other.tag = "next"; @spec.tag = "next"
199
+ @spec.should === @other
200
+ end
201
+
202
+ it "should not match a walk spec with a different tag" do
203
+ @other.tag = "next"; @spec.tag = "previous"
204
+ @spec.should_not === @other
205
+ end
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,30 @@
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
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
+
17
+ require 'rubygems' # Use the gems path only for the spec suite
18
+ require 'riak'
19
+ require 'rspec/autorun'
20
+ require 'fakeweb'
21
+
22
+ Dir[File.join(File.dirname(__FILE__), "support", "*.rb")].each {|f| require f }
23
+
24
+ Rspec.configure do |config|
25
+ config.mock_with :rspec
26
+
27
+ config.before(:each) do
28
+ FakeWeb.clean_registry
29
+ end
30
+ end
@@ -0,0 +1,215 @@
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
+ shared_examples_for "HTTP backend" do
15
+ describe "HEAD requests" do
16
+ before :each do
17
+ setup_http_mock(:head, @backend.path("/riak/","foo").to_s, :body => "")
18
+ end
19
+
20
+ it "should return only the headers when the request succeeds" do
21
+ response = @backend.head(200, "/riak/","foo")
22
+ response.should_not have_key(:body)
23
+ response[:headers].should be_kind_of(Hash)
24
+ response[:code].should == 200
25
+ end
26
+
27
+ it "should raise a FailedRequest exception when the request fails" do
28
+ lambda { @backend.head(301, "/riak/", "foo") }.should raise_error(Riak::FailedRequest)
29
+ end
30
+
31
+ it "should raise an error if an invalid resource path is given" do
32
+ lambda { @backend.head(200, "/riak/") }.should raise_error(ArgumentError)
33
+ end
34
+
35
+ it "should not raise a FailedRequest if one of the expected response codes matches" do
36
+ lambda { @backend.head([200, 301], "/riak/", "foo") }.should_not raise_error(Riak::FailedRequest)
37
+ end
38
+ end
39
+
40
+ describe "GET requests" do
41
+ before :each do
42
+ setup_http_mock(:get, @backend.path("/riak/","foo").to_s, :body => "Success!")
43
+ end
44
+
45
+ it "should return the response body and headers when the request succeeds" do
46
+ response = @backend.get(200, "/riak/","foo")
47
+ response[:body].should == "Success!"
48
+ response[:headers].should be_kind_of(Hash)
49
+ response[:code].should == 200
50
+ end
51
+
52
+ it "should raise a FailedRequest exception when the request fails" do
53
+ lambda { @backend.get(304, "/riak/","foo") }.should raise_error(Riak::FailedRequest)
54
+ end
55
+
56
+ it "should not raise a FailedRequest if one of the expected response codes matches" do
57
+ lambda { @backend.get([200, 301], "/riak/","foo") }.should_not raise_error(Riak::FailedRequest)
58
+ end
59
+
60
+ it "should yield successive chunks of the response to the given block but not return the entire body" do
61
+ chunks = ""
62
+ response = @backend.get(200, "/riak/","foo") do |chunk|
63
+ chunks << chunk
64
+ end
65
+ chunks.should == "Success!"
66
+ response.should_not have_key(:body)
67
+ response[:headers].should be_kind_of(Hash)
68
+ response[:code].should == 200
69
+ end
70
+
71
+ it "should raise an error if an invalid resource path is given" do
72
+ lambda { @backend.get(200, "/riak/") }.should raise_error(ArgumentError)
73
+ end
74
+ end
75
+
76
+ describe "DELETE requests" do
77
+ before :each do
78
+ setup_http_mock(:delete, @backend.path("/riak/","foo").to_s, :body => "Success!")
79
+ end
80
+
81
+ it "should return the response body and headers when the request succeeds" do
82
+ response = @backend.delete(200, "/riak/","foo")
83
+ response[:body].should == "Success!"
84
+ response[:headers].should be_kind_of(Hash)
85
+ end
86
+
87
+ it "should raise a FailedRequest exception when the request fails" do
88
+ lambda { @backend.delete(304, "/riak/","foo") }.should raise_error(Riak::FailedRequest)
89
+ end
90
+
91
+ it "should not raise a FailedRequest if one of the expected response codes matches" do
92
+ lambda { @backend.delete([200, 301], "/riak/","foo") }.should_not raise_error(Riak::FailedRequest)
93
+ end
94
+
95
+ it "should yield successive chunks of the response to the given block but not return the entire body" do
96
+ chunks = ""
97
+ response = @backend.delete(200, "/riak/","foo") do |chunk|
98
+ chunks << chunk
99
+ end
100
+ chunks.should == "Success!"
101
+ response.should_not have_key(:body)
102
+ response[:headers].should be_kind_of(Hash)
103
+ response[:code].should == 200
104
+ end
105
+
106
+ it "should raise an error if an invalid resource path is given" do
107
+ lambda { @backend.delete(200, "/riak/") }.should raise_error(ArgumentError)
108
+ end
109
+ end
110
+
111
+ describe "PUT requests" do
112
+ before :each do
113
+ setup_http_mock(:put, @backend.path("/riak/","foo").to_s, :body => "Success!")
114
+ end
115
+
116
+ it "should return the response body, headers, and code when the request succeeds" do
117
+ response = @backend.put(200, "/riak/","foo", "This is the body.")
118
+ response[:body].should == "Success!"
119
+ response[:headers].should be_kind_of(Hash)
120
+ response[:code].should == 200
121
+ end
122
+
123
+ it "should raise a FailedRequest exception when the request fails" do
124
+ lambda { @backend.put(204, "/riak/","foo", "This is the body.") }.should raise_error(Riak::FailedRequest)
125
+ end
126
+
127
+ it "should not raise a FailedRequest if one of the expected response codes matches" do
128
+ lambda { @backend.put([200, 204], "/riak/","foo", "This is the body.") }.should_not raise_error(Riak::FailedRequest)
129
+ end
130
+
131
+
132
+ it "should yield successive chunks of the response to the given block but not return the entire body" do
133
+ chunks = ""
134
+ response = @backend.put(200, "/riak/","foo", "This is the body.") do |chunk|
135
+ chunks << chunk
136
+ end
137
+ chunks.should == "Success!"
138
+ response.should_not have_key(:body)
139
+ response[:headers].should be_kind_of(Hash)
140
+ response[:code].should == 200
141
+ end
142
+
143
+ it "should raise an error if an invalid resource path is given" do
144
+ lambda { @backend.put(200, "/riak/") }.should raise_error(ArgumentError)
145
+ end
146
+
147
+ it "should raise an error if no body data is given" do
148
+ lambda { @backend.put(200, "/riak/","foo") }.should raise_error(ArgumentError)
149
+ end
150
+
151
+ it "should raise an error if the body is not a string" do
152
+ lambda { @backend.put(200, "/riak/","foo", 123) }.should raise_error(ArgumentError)
153
+ end
154
+ end
155
+
156
+ describe "POST requests" do
157
+ before :each do
158
+ setup_http_mock(:post, @backend.path("/riak/","foo").to_s, :body => "Success!")
159
+ end
160
+
161
+ it "should return the response body, headers, and code when the request succeeds" do
162
+ response = @backend.post(200, "/riak/","foo", "This is the body.")
163
+ response[:body].should == "Success!"
164
+ response[:headers].should be_kind_of(Hash)
165
+ response[:code].should == 200
166
+ end
167
+
168
+ it "should raise a FailedRequest exception when the request fails" do
169
+ lambda { @backend.post(204, "/riak/", "foo", "This is the body.") }.should raise_error(Riak::FailedRequest)
170
+ end
171
+
172
+ it "should not raise a FailedRequest if one of the expected response codes matches" do
173
+ lambda { @backend.post([200, 204], "/riak/", "foo", "This is the body.") }.should_not raise_error(Riak::FailedRequest)
174
+ end
175
+
176
+ it "should yield successive chunks of the response to the given block but not return the entire body" do
177
+ chunks = ""
178
+ response = @backend.post(200, "/riak/", "foo", "This is the body.") do |chunk|
179
+ chunks << chunk
180
+ end
181
+ chunks.should == "Success!"
182
+ response.should_not have_key(:body)
183
+ response[:headers].should be_kind_of(Hash)
184
+ response[:code].should == 200
185
+ end
186
+
187
+ it "should raise an error if an invalid resource path is given" do
188
+ lambda { @backend.post(200, "/riak/") }.should raise_error(ArgumentError)
189
+ end
190
+
191
+ it "should raise an error if no body data is given" do
192
+ lambda { @backend.post(200, "/riak/", "foo") }.should raise_error(ArgumentError)
193
+ end
194
+
195
+ it "should raise an error if the body is not a string" do
196
+ lambda { @backend.post(200, "/riak/", "foo", 123) }.should raise_error(ArgumentError)
197
+ end
198
+ end
199
+
200
+ describe "Responses with no body" do
201
+ [204, 205, 304].each do |code|
202
+ [:get, :post, :put, :delete].each do |method|
203
+ it "should not return a body on #{method.to_s.upcase} for #{code}" do
204
+ setup_http_mock(method, @backend.path("/riak/","foo").to_s, :status => code)
205
+ response = if method == :post || method == :put
206
+ @backend.send(method, code,"/riak/","foo", "This is the body")
207
+ else
208
+ @backend.send(method, code, "/riak/", "foo")
209
+ end
210
+ response.should_not have_key(:body)
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end