riak-client 0.9.8 → 1.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. data/.gitignore +32 -0
  2. data/Gemfile +17 -11
  3. data/Guardfile +14 -0
  4. data/Rakefile +18 -44
  5. data/erl_src/riak_kv_test_backend.beam +0 -0
  6. data/erl_src/riak_kv_test_backend.erl +461 -128
  7. data/erl_src/riak_search_test_backend.beam +0 -0
  8. data/erl_src/riak_search_test_backend.erl +175 -0
  9. data/lib/active_support/cache/riak_store.rb +0 -13
  10. data/lib/riak.rb +11 -16
  11. data/lib/riak/bucket.rb +59 -41
  12. data/lib/riak/cache_store.rb +1 -14
  13. data/lib/riak/client.rb +145 -73
  14. data/lib/riak/client/beefcake/messages.rb +36 -31
  15. data/lib/riak/client/beefcake/object_methods.rb +27 -19
  16. data/lib/riak/client/beefcake_protobuffs_backend.rb +27 -33
  17. data/lib/riak/client/excon_backend.rb +0 -13
  18. data/lib/riak/client/http_backend.rb +95 -60
  19. data/lib/riak/client/http_backend/configuration.rb +144 -19
  20. data/lib/riak/client/http_backend/key_streamer.rb +1 -14
  21. data/lib/riak/client/http_backend/object_methods.rb +16 -16
  22. data/lib/riak/client/http_backend/request_headers.rb +0 -13
  23. data/lib/riak/client/http_backend/transport_methods.rb +26 -56
  24. data/lib/riak/client/net_http_backend.rb +11 -13
  25. data/lib/riak/client/protobuffs_backend.rb +21 -19
  26. data/lib/riak/client/pump.rb +1 -15
  27. data/lib/riak/client/search.rb +85 -0
  28. data/lib/riak/cluster.rb +151 -0
  29. data/lib/riak/core_ext.rb +1 -0
  30. data/lib/riak/core_ext/deep_dup.rb +13 -0
  31. data/lib/riak/core_ext/json.rb +15 -0
  32. data/lib/riak/core_ext/stringify_keys.rb +1 -1
  33. data/lib/riak/core_ext/symbolize_keys.rb +1 -1
  34. data/lib/riak/encoding.rb +6 -0
  35. data/lib/riak/failed_request.rb +2 -15
  36. data/lib/riak/i18n.rb +0 -13
  37. data/lib/riak/json.rb +19 -8
  38. data/lib/riak/link.rb +18 -20
  39. data/lib/riak/locale/en.yml +13 -16
  40. data/lib/riak/map_reduce.rb +40 -20
  41. data/lib/riak/map_reduce/filter_builder.rb +14 -18
  42. data/lib/riak/map_reduce/phase.rb +0 -13
  43. data/lib/riak/map_reduce_error.rb +0 -13
  44. data/lib/riak/node.rb +38 -0
  45. data/lib/riak/node/configuration.rb +286 -0
  46. data/lib/riak/node/console.rb +139 -0
  47. data/lib/riak/node/control.rb +207 -0
  48. data/lib/riak/node/defaults.rb +70 -0
  49. data/lib/riak/node/generation.rb +99 -0
  50. data/lib/riak/node/log.rb +34 -0
  51. data/lib/riak/node/version.rb +37 -0
  52. data/lib/riak/robject.rb +45 -41
  53. data/lib/riak/search.rb +2 -161
  54. data/lib/riak/serializers.rb +74 -0
  55. data/lib/riak/stamp.rb +77 -0
  56. data/lib/riak/test_server.rb +56 -220
  57. data/lib/riak/util/escape.rb +58 -17
  58. data/lib/riak/util/headers.rb +2 -15
  59. data/lib/riak/util/multipart.rb +0 -13
  60. data/lib/riak/util/multipart/stream_parser.rb +0 -13
  61. data/lib/riak/util/tcp_socket_extensions.rb +1 -14
  62. data/lib/riak/util/translation.rb +0 -13
  63. data/lib/riak/version.rb +3 -0
  64. data/lib/riak/walk_spec.rb +0 -13
  65. data/riak-client.gemspec +27 -47
  66. data/spec/fixtures/multipart-with-marked-tombstones.txt +17 -0
  67. data/spec/fixtures/multipart-with-unmarked-tombstone.txt +16 -0
  68. data/spec/integration/riak/cache_store_spec.rb +2 -40
  69. data/spec/integration/riak/cluster_spec.rb +88 -0
  70. data/spec/integration/riak/http_backends_spec.rb +6 -30
  71. data/spec/integration/riak/node_spec.rb +184 -0
  72. data/spec/integration/riak/protobuffs_backends_spec.rb +2 -26
  73. data/spec/integration/riak/test_server_spec.rb +31 -167
  74. data/spec/riak/beefcake_protobuffs_backend_spec.rb +5 -4
  75. data/spec/riak/bucket_spec.rb +26 -36
  76. data/spec/riak/client_spec.rb +44 -38
  77. data/spec/riak/escape_spec.rb +56 -30
  78. data/spec/riak/excon_backend_spec.rb +4 -17
  79. data/spec/riak/headers_spec.rb +1 -14
  80. data/spec/riak/http_backend/configuration_spec.rb +211 -34
  81. data/spec/riak/http_backend/object_methods_spec.rb +52 -18
  82. data/spec/riak/http_backend/transport_methods_spec.rb +5 -38
  83. data/spec/riak/http_backend_spec.rb +84 -78
  84. data/spec/riak/link_spec.rb +19 -18
  85. data/spec/riak/map_reduce/filter_builder_spec.rb +1 -14
  86. data/spec/riak/map_reduce/phase_spec.rb +1 -14
  87. data/spec/riak/map_reduce_spec.rb +141 -43
  88. data/spec/riak/multipart_spec.rb +1 -14
  89. data/spec/riak/net_http_backend_spec.rb +2 -15
  90. data/spec/riak/robject_spec.rb +129 -97
  91. data/spec/riak/search_spec.rb +45 -62
  92. data/spec/riak/serializers_spec.rb +93 -0
  93. data/spec/riak/stamp_spec.rb +54 -0
  94. data/spec/riak/stream_parser_spec.rb +3 -16
  95. data/spec/riak/walk_spec_spec.rb +1 -14
  96. data/spec/spec_helper.rb +22 -27
  97. data/spec/support/http_backend_implementation_examples.rb +49 -79
  98. data/spec/support/integration_setup.rb +10 -0
  99. data/spec/support/mock_server.rb +0 -14
  100. data/spec/support/mocks.rb +0 -13
  101. data/spec/support/test_server.rb +30 -0
  102. data/spec/support/test_server.yml.example +14 -2
  103. data/spec/support/unified_backend_examples.rb +36 -27
  104. metadata +100 -31
  105. data/lib/riak/client/curb_backend.rb +0 -89
  106. data/spec/riak/curb_backend_spec.rb +0 -76
@@ -1,17 +1,4 @@
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__))
1
+ require 'spec_helper'
15
2
 
16
3
  describe Riak::Bucket do
17
4
  before :each do
@@ -38,17 +25,11 @@ describe Riak::Bucket do
38
25
  end
39
26
 
40
27
  describe "accessing keys" do
41
- it "should load the keys if not present" do
28
+ it "should list the keys" do
42
29
  @backend.should_receive(:list_keys).with(@bucket).and_return(["bar"])
43
30
  @bucket.keys.should == ["bar"]
44
31
  end
45
32
 
46
- it "should allow reloading of the keys" do
47
- @backend.should_receive(:list_keys).with(@bucket).and_return(["bar"])
48
- @bucket.instance_variable_set(:@keys, ["foo"])
49
- @bucket.keys(:reload => true).should == ["bar"]
50
- end
51
-
52
33
  it "should allow streaming keys through block" do
53
34
  @backend.should_receive(:list_keys).with(@bucket).and_yield([]).and_yield(["bar"]).and_yield(["baz"])
54
35
  all_keys = []
@@ -58,15 +39,17 @@ describe Riak::Bucket do
58
39
  all_keys.should == ["bar", "baz"]
59
40
  end
60
41
 
61
- it "should invalidate the key cache when streaming" do
62
- @backend.should_receive(:list_keys).once.and_return(['a'])
63
- @backend.should_receive(:list_keys).once.and_yield(['b'])
64
- @backend.should_receive(:list_keys).once.and_return(['c'])
65
- @bucket.keys.should == ['a']
66
- keys = []
67
- @bucket.keys {|kl| keys.concat(kl) }
68
- keys.should == ['b']
69
- @bucket.keys.should == ['c']
42
+ it "should not cache the list of keys" do
43
+ @backend.should_receive(:list_keys).with(@bucket).twice.and_return(["bar"])
44
+ 2.times { @bucket.keys.should == ['bar'] }
45
+ end
46
+
47
+ it "should warn about the expense of list-keys when warnings are not disabled" do
48
+ Riak.disable_list_keys_warnings = false
49
+ @backend.stub!(:list_keys).and_return(%w{test test2})
50
+ @bucket.should_receive(:warn)
51
+ @bucket.keys
52
+ Riak.disable_list_keys_warnings = true
70
53
  end
71
54
  end
72
55
 
@@ -104,12 +87,12 @@ describe Riak::Bucket do
104
87
 
105
88
  describe "fetching an object" do
106
89
  it "should fetch the object via the backend" do
107
- @backend.should_receive(:fetch_object).with(@bucket, "db", nil).and_return(nil)
90
+ @backend.should_receive(:fetch_object).with(@bucket, "db", {}).and_return(nil)
108
91
  @bucket.get("db")
109
92
  end
110
93
 
111
94
  it "should use the specified R quroum" do
112
- @backend.should_receive(:fetch_object).with(@bucket, "db", 2).and_return(nil)
95
+ @backend.should_receive(:fetch_object).with(@bucket, "db", {:r => 2}).and_return(nil)
113
96
  @bucket.get("db", :r => 2)
114
97
  end
115
98
  end
@@ -126,7 +109,7 @@ describe Riak::Bucket do
126
109
  describe "fetching or creating a new object" do
127
110
  it "should return the existing object if present" do
128
111
  @object = mock("RObject")
129
- @backend.should_receive(:fetch_object).with(@bucket,"db", nil).and_return(@object)
112
+ @backend.should_receive(:fetch_object).with(@bucket,"db", {}).and_return(@object)
130
113
  @bucket.get_or_new('db').should == @object
131
114
  end
132
115
 
@@ -144,11 +127,18 @@ describe Riak::Bucket do
144
127
 
145
128
  it "should pass along the given R quorum parameter" do
146
129
  @object = mock("RObject")
147
- @backend.should_receive(:fetch_object).with(@bucket,"db", "all").and_return(@object)
130
+ @backend.should_receive(:fetch_object).with(@bucket,"db", {:r => "all"}).and_return(@object)
148
131
  @bucket.get_or_new('db', :r => "all").should == @object
149
132
  end
150
133
  end
151
134
 
135
+ describe "querying an index" do
136
+ it "should list the matching keys" do
137
+ @backend.should_receive(:get_index).with(@bucket, "test_bin", "testing").and_return(["bar"])
138
+ @bucket.get_index("test_bin", "testing").should == ["bar"]
139
+ end
140
+ end
141
+
152
142
  describe "get/set allow_mult property" do
153
143
  before :each do
154
144
  @backend.stub!(:get_bucket_props).and_return({"allow_mult" => false})
@@ -210,12 +200,12 @@ describe Riak::Bucket do
210
200
 
211
201
  describe "deleting an object" do
212
202
  it "should delete a key from within the bucket" do
213
- @backend.should_receive(:delete_object).with(@bucket, "bar", nil)
203
+ @backend.should_receive(:delete_object).with(@bucket, "bar", {})
214
204
  @bucket.delete('bar')
215
205
  end
216
206
 
217
207
  it "should use the specified RW quorum" do
218
- @backend.should_receive(:delete_object).with(@bucket, "bar", "all")
208
+ @backend.should_receive(:delete_object).with(@bucket, "bar", {:rw => "all"})
219
209
  @bucket.delete('bar', :rw => "all")
220
210
  end
221
211
  end
@@ -1,17 +1,4 @@
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__))
1
+ require 'spec_helper'
15
2
 
16
3
  describe Riak::Client do
17
4
  describe "when initializing" do
@@ -74,23 +61,33 @@ describe Riak::Client do
74
61
 
75
62
  it "should accept a mapreduce path" do
76
63
  client = Riak::Client.new(:mapred => "/mr")
77
- client.mapred.should == "/mr"
64
+ client.http_paths[:mapred].should == "/mr"
78
65
  end
79
66
 
80
67
  it "should default the mapreduce path to /mapred if not specified" do
81
- Riak::Client.new.mapred.should == "/mapred"
68
+ Riak::Client.new.http_paths[:mapred].should == "/mapred"
82
69
  end
83
70
 
84
71
  it "should accept a luwak path" do
85
72
  client = Riak::Client.new(:luwak => "/beans")
86
- client.luwak.should == "/beans"
73
+ client.http_paths[:luwak].should == "/beans"
87
74
  end
88
75
 
89
76
  it "should default the luwak path to /luwak if not specified" do
90
- Riak::Client.new.luwak.should == "/luwak"
77
+ Riak::Client.new.http_paths[:luwak].should == "/luwak"
78
+ end
79
+
80
+ it "should accept a solr path" do
81
+ client = Riak::Client.new(:solr => "/solar")
82
+ client.http_paths[:solr].should == "/solar"
91
83
  end
92
84
  end
93
85
 
86
+ it "should expose a Stamp object" do
87
+ subject.should respond_to(:stamp)
88
+ subject.stamp.should be_kind_of(Riak::Stamp)
89
+ end
90
+
94
91
  describe "reconfiguring" do
95
92
  before :each do
96
93
  @client = Riak::Client.new
@@ -180,6 +177,8 @@ describe Riak::Client do
180
177
  end
181
178
 
182
179
  it "should allow setting the prefix" do
180
+ @client.http_paths.should be_kind_of(Hash)
181
+ @client.http_paths.include?(:prefix).should == true
183
182
  @client.should respond_to(:prefix=)
184
183
  @client.prefix = "/another-prefix"
185
184
  @client.prefix.should == "/another-prefix"
@@ -210,11 +209,9 @@ describe Riak::Client do
210
209
  @client.http_backend = :NetHTTP
211
210
  @client.http.should be_instance_of(Riak::Client::NetHTTPBackend)
212
211
 
213
- unless defined? JRUBY_VERSION
214
- @client = Riak::Client.new
215
- @client.http_backend = :Curb
216
- @client.http.should be_instance_of(Riak::Client::CurbBackend)
217
- end
212
+ @client = Riak::Client.new
213
+ @client.http_backend = :Excon
214
+ @client.http.should be_instance_of(Riak::Client::ExconBackend)
218
215
  end
219
216
 
220
217
  it "should raise an error when the chosen backend is not valid" do
@@ -273,11 +270,6 @@ describe Riak::Client do
273
270
  @client.bucket("foo", :props => true)
274
271
  end
275
272
 
276
- it "should fetch keys if asked" do
277
- @backend.should_receive(:list_keys) {|b| b.name.should == "foo"; ["bar"] }
278
- @client.bucket("foo", :keys => true)
279
- end
280
-
281
273
  it "should memoize bucket parameters" do
282
274
  @bucket = mock("Bucket")
283
275
  Riak::Bucket.should_receive(:new).with(@client, "baz").once.and_return(@bucket)
@@ -286,16 +278,30 @@ describe Riak::Client do
286
278
  end
287
279
  end
288
280
 
289
- it "should list buckets" do
290
- @client = Riak::Client.new
291
- @backend = mock("Backend")
292
- @client.stub!(:backend).and_return(@backend)
293
- @backend.should_receive(:list_buckets).and_return(%w{test test2})
294
- buckets = @client.buckets
295
- buckets.should have(2).items
296
- buckets.should be_all {|b| b.is_a?(Riak::Bucket) }
297
- buckets[0].name.should == "test"
298
- buckets[1].name.should == "test2"
281
+ describe "listing buckets" do
282
+ before do
283
+ @client = Riak::Client.new
284
+ @backend = mock("Backend")
285
+ @client.stub!(:backend).and_return(@backend)
286
+ end
287
+
288
+ after { Riak.disable_list_keys_warnings = true }
289
+
290
+ it "should list buckets" do
291
+ @backend.should_receive(:list_buckets).and_return(%w{test test2})
292
+ buckets = @client.buckets
293
+ buckets.should have(2).items
294
+ buckets.should be_all {|b| b.is_a?(Riak::Bucket) }
295
+ buckets[0].name.should == "test"
296
+ buckets[1].name.should == "test2"
297
+ end
298
+
299
+ it "should warn about the expense of list-buckets when warnings are not disabled" do
300
+ Riak.disable_list_keys_warnings = false
301
+ @backend.stub!(:list_buckets).and_return(%w{test test2})
302
+ @client.should_receive(:warn)
303
+ @client.buckets
304
+ end
299
305
  end
300
306
 
301
307
  describe "Luwak (large-files) support" do
@@ -1,18 +1,5 @@
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
-
15
- require File.expand_path("../../spec_helper", __FILE__)
1
+
2
+ require 'spec_helper'
16
3
 
17
4
  describe Riak::Util::Escape do
18
5
  before :each do
@@ -20,24 +7,63 @@ describe Riak::Util::Escape do
20
7
  @object.extend(Riak::Util::Escape)
21
8
  end
22
9
 
23
- it "should escape standard non-safe characters" do
24
- @object.escape("some string").should == "some%20string"
25
- @object.escape("another^one").should == "another%5Eone"
26
- @object.escape("bracket[one").should == "bracket%5Bone"
10
+ it "should use URI by default for escaping" do
11
+ Riak.escaper.should == URI
27
12
  end
28
13
 
29
- it "should escape slashes" do
30
- @object.escape("some/inner/path").should == "some%2Finner%2Fpath"
31
- end
32
-
33
- it "should convert the bucket or key to a string before escaping" do
34
- @object.escape(125).should == '125'
14
+ context "when using CGI for escaping" do
15
+ before { @oldesc, Riak.escaper = Riak.escaper, CGI }
16
+ after { Riak.escaper = @oldesc }
17
+
18
+ it "should escape standard non-safe characters" do
19
+ @object.escape("some string").should == "some%20string"
20
+ @object.escape("another^one").should == "another%5Eone"
21
+ @object.escape("bracket[one").should == "bracket%5Bone"
22
+ end
23
+
24
+ it "should escape slashes" do
25
+ @object.escape("some/inner/path").should == "some%2Finner%2Fpath"
26
+ end
27
+
28
+ it "should convert the bucket or key to a string before escaping" do
29
+ @object.escape(125).should == '125'
30
+ end
31
+
32
+ it "should unescape escaped strings" do
33
+ @object.unescape("some%20string").should == "some string"
34
+ @object.unescape("another%5Eone").should == "another^one"
35
+ @object.unescape("bracket%5Bone").should == "bracket[one"
36
+ @object.unescape("some%2Finner%2Fpath").should == "some/inner/path"
37
+ end
35
38
  end
36
39
 
37
- it "should unescape escaped strings" do
38
- @object.unescape("some%20string").should == "some string"
39
- @object.unescape("another%5Eone").should == "another^one"
40
- @object.unescape("bracket%5Bone").should == "bracket[one"
41
- @object.unescape("some%2Finner%2Fpath").should == "some/inner/path"
40
+ context "when using URI for escaping" do
41
+ before { @oldesc, Riak.escaper = Riak.escaper, URI }
42
+ after { Riak.escaper = @oldesc }
43
+
44
+ it "should escape standard non-safe characters" do
45
+ @object.escape("some string").should == "some%20string"
46
+ @object.escape("another^one").should == "another%5Eone"
47
+ end
48
+
49
+ it "should allow URI-safe characters" do
50
+ @object.escape("bracket[one").should == "bracket[one"
51
+ @object.escape("sean@basho").should == "sean@basho"
52
+ end
53
+
54
+ it "should escape slashes" do
55
+ @object.escape("some/inner/path").should == "some%2Finner%2Fpath"
56
+ end
57
+
58
+ it "should convert the bucket or key to a string before escaping" do
59
+ @object.escape(125).should == '125'
60
+ end
61
+
62
+ it "should unescape escaped strings" do
63
+ @object.unescape("some%20string").should == "some string"
64
+ @object.unescape("another%5Eone").should == "another^one"
65
+ @object.unescape("bracket%5Bone").should == "bracket[one"
66
+ @object.unescape("some%2Finner%2Fpath").should == "some/inner/path"
67
+ end
42
68
  end
43
69
  end
@@ -1,17 +1,4 @@
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__))
1
+ require 'spec_helper'
15
2
 
16
3
  begin
17
4
  require 'excon'
@@ -54,7 +41,7 @@ else
54
41
  # can it?
55
42
  setup_http_mock(:put, @backend.path("/riak/","foo").to_s, :body => "ok")
56
43
  lambda do
57
- @backend.put(200, "/riak/", "foo", "body",{"Long-Header" => (["12345678"*10]*100).join(", ") })
44
+ @backend.put(200, @backend.path("/riak", "foo"), "body", {"Long-Header" => (["12345678"*10]*100).join(", ") })
58
45
  end.should_not raise_error
59
46
  end
60
47
 
@@ -62,13 +49,13 @@ else
62
49
  file = File.open(File.expand_path("../../fixtures/cat.jpg", __FILE__), 'rb')
63
50
  lambda do
64
51
  setup_http_mock(:put, @backend.path("/riak/","foo").to_s, :body => "ok")
65
- @backend.put(200, "/riak/", "foo", file, {})
52
+ @backend.put(200, @backend.path("/riak/","foo"), file)
66
53
  $mock_server.satisfied.should be_true
67
54
  end.should_not raise_error
68
55
  file.rewind # Have to rewind the file or we hang
69
56
  lambda do
70
57
  setup_http_mock(:post, @backend.path("/riak/","foo").to_s, :body => "ok")
71
- @backend.post(200, "/riak/", "foo", file, {})
58
+ @backend.post(200, @backend.path("/riak/", "foo"), file)
72
59
  $mock_server.satisfied.should be_true
73
60
  end.should_not raise_error
74
61
  end
@@ -1,17 +1,4 @@
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__))
1
+ require 'spec_helper'
15
2
 
16
3
  describe Riak::Util::Headers do
17
4
  it "should include the Net::HTTPHeader module" do
@@ -1,28 +1,203 @@
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__))
1
+ require 'spec_helper'
15
2
 
16
3
  describe Riak::Client::HTTPBackend::Configuration do
17
- before do
18
- @client = Riak::Client.new
19
- @backend = Riak::Client::HTTPBackend.new(@client)
4
+ let(:client){ Riak::Client.new }
5
+ subject { Riak::Client::HTTPBackend.new(client) }
6
+ let(:uri){ URI.parse("http://127.0.0.1:8098/") }
7
+
8
+ context "generating resource URIs" do
9
+ context "when using the old scheme" do
10
+ before { subject.should_receive(:get).with(200, uri).and_return(:headers => {'link' => ['</riak>; rel="riak_kv_wm_raw", </ping>; rel="riak_kv_wm_ping", </stats>; rel="riak_kv_wm_stats", </mapred>; rel="riak_kv_wm_mapred"']}) }
11
+
12
+ it "should generate a ping path" do
13
+ url = subject.ping_path
14
+ url.should be_kind_of(URI)
15
+ url.path.should == '/ping'
16
+ end
17
+
18
+ it "should generate a stats path" do
19
+ url = subject.stats_path
20
+ url.should be_kind_of(URI)
21
+ url.path.should == '/stats'
22
+ end
23
+
24
+ it "should generate a mapred path" do
25
+ url = subject.mapred_path :chunked => true
26
+ url.should be_kind_of(URI)
27
+ url.path.should == '/mapred'
28
+ url.query.should == "chunked=true"
29
+ end
30
+
31
+ it "should generate a bucket list path" do
32
+ url = subject.bucket_list_path
33
+ url.should be_kind_of(URI)
34
+ url.path.should == '/riak'
35
+ url.query.should == 'buckets=true'
36
+ end
37
+
38
+ it "should generate a bucket properties path" do
39
+ url = subject.bucket_properties_path('test ')
40
+ url.should be_kind_of(URI)
41
+ url.path.should == '/riak/test%20'
42
+ url.query.should == "keys=false&props=true"
43
+ end
44
+
45
+ it "should generate a key list path" do
46
+ url = subject.key_list_path('test ')
47
+ url.should be_kind_of(URI)
48
+ url.path.should == '/riak/test%20'
49
+ url.query.should == 'keys=true&props=false'
50
+ url = subject.key_list_path('test ', :keys => :stream)
51
+ url.path.should == '/riak/test%20'
52
+ url.query.should == 'keys=stream&props=false'
53
+ end
54
+
55
+ it "should generate an object path" do
56
+ url = subject.object_path('test ', 'object/', :r => 3)
57
+ url.should be_kind_of(URI)
58
+ url.path.should == '/riak/test%20/object%2F'
59
+ url.query.should == 'r=3'
60
+ end
61
+
62
+ it "should generate a link-walking path" do
63
+ url = subject.link_walk_path('test ', 'object/', [Riak::WalkSpec.new(:bucket => 'foo')])
64
+ url.should be_kind_of(URI)
65
+ url.path.should == '/riak/test%20/object%2F/foo,_,_'
66
+ end
67
+
68
+ it "should raise an error when generating an index range path" do
69
+ expect { subject.index_range_path('test', 'index_bin', 'a', 'b') }.to raise_error
70
+ end
71
+
72
+ it "should raise an error when generating an index equal path" do
73
+ expect { subject.index_eq_path('test', 'index_bin', 'a') }.to raise_error
74
+ end
75
+ end
76
+
77
+ context "when using the new scheme" do
78
+ before { subject.should_receive(:get).with(200, uri).and_return(:headers => {'link' => ['</buckets>; rel="riak_kv_wm_buckets", </ping>; rel="riak_kv_wm_ping", </stats>; rel="riak_kv_wm_stats", </mapred>; rel="riak_kv_wm_mapred"']}) }
79
+
80
+ it "should generate a ping path" do
81
+ url = subject.ping_path
82
+ url.should be_kind_of(URI)
83
+ url.path.should == '/ping'
84
+ end
85
+
86
+ it "should generate a stats path" do
87
+ url = subject.stats_path
88
+ url.should be_kind_of(URI)
89
+ url.path.should == '/stats'
90
+ end
91
+
92
+ it "should generate a mapred path" do
93
+ url = subject.mapred_path :chunked => true
94
+ url.should be_kind_of(URI)
95
+ url.path.should == '/mapred'
96
+ url.query.should == "chunked=true"
97
+ end
98
+
99
+ it "should generate a bucket list path" do
100
+ url = subject.bucket_list_path
101
+ url.should be_kind_of(URI)
102
+ url.path.should == '/buckets'
103
+ url.query.should == 'buckets=true'
104
+ end
105
+
106
+ it "should generate a bucket properties path" do
107
+ url = subject.bucket_properties_path('test ')
108
+ url.should be_kind_of(URI)
109
+ url.path.should == '/buckets/test%20/props'
110
+ url.query.should be_nil
111
+ end
112
+
113
+ it "should generate a key list path" do
114
+ url = subject.key_list_path('test ')
115
+ url.should be_kind_of(URI)
116
+ url.path.should == '/buckets/test%20/keys'
117
+ url.query.should == 'keys=true'
118
+ url = subject.key_list_path('test ', :keys => :stream)
119
+ url.path.should == '/buckets/test%20/keys'
120
+ url.query.should == 'keys=stream'
121
+ end
122
+
123
+ it "should generate an object path" do
124
+ url = subject.object_path('test ', 'object/', :r => 3)
125
+ url.should be_kind_of(URI)
126
+ url.path.should == '/buckets/test%20/keys/object%2F'
127
+ url.query.should == 'r=3'
128
+ end
129
+
130
+ it "should generate a link-walking path" do
131
+ url = subject.link_walk_path('test ', 'object/', [Riak::WalkSpec.new(:bucket => 'foo')])
132
+ url.should be_kind_of(URI)
133
+ url.path.should == '/buckets/test%20/keys/object%2F/foo,_,_'
134
+ end
135
+
136
+ it "should generate an index range path" do
137
+ url = subject.index_range_path('test ', 'test_bin', 'a', 'b')
138
+ url.should be_kind_of(URI)
139
+ url.path.should == '/buckets/test%20/index/test_bin/a/b'
140
+ end
141
+
142
+ it "should generate an index equal path" do
143
+ url = subject.index_eq_path('test ', 'test_bin', 'a')
144
+ url.should be_kind_of(URI)
145
+ url.path.should == '/buckets/test%20/index/test_bin/a'
146
+ end
147
+ end
20
148
  end
21
149
 
22
150
  it "should memoize the server config" do
23
- @backend.should_receive(:get).with(200, "/", {}, {}).once.and_return(:headers => {'link' => ['</riak>; rel="riak_kv_wm_link_walker",</mapred>; rel="riak_kv_wm_mapred",</ping>; rel="riak_kv_wm_ping",</riak>; rel="riak_kv_wm_raw",</stats>; rel="riak_kv_wm_stats"']})
24
- @backend.send(:riak_kv_wm_link_walker).should == "/riak"
25
- @backend.send(:riak_kv_wm_raw).should == "/riak"
151
+ subject.should_receive(:get).with(200, uri).once.and_return(:headers => {'link' => ['</riak>; rel="riak_kv_wm_link_walker",</mapred>; rel="riak_kv_wm_mapred",</ping>; rel="riak_kv_wm_ping",</riak>; rel="riak_kv_wm_raw",</stats>; rel="riak_kv_wm_stats"']})
152
+ subject.send(:riak_kv_wm_link_walker).should == "/riak"
153
+ subject.send(:riak_kv_wm_raw).should == "/riak"
154
+ end
155
+
156
+ context "generating Solr paths" do
157
+ context "when Riak Search is disabled" do
158
+ before {
159
+ subject.should_receive(:get).with(200, uri).once.and_return(:headers => {'link' => ['</riak>; rel="riak_kv_wm_link_walker",</mapred>; rel="riak_kv_wm_mapred",</ping>; rel="riak_kv_wm_ping",</riak>; rel="riak_kv_wm_raw",</stats>; rel="riak_kv_wm_stats"']})
160
+ }
161
+
162
+ it "should raise an error" do
163
+ expect { subject.solr_select_path('foo', 'a:b') }.to raise_error
164
+ expect { subject.solr_update_path('foo') }.to raise_error
165
+ end
166
+ end
167
+
168
+ context "when Riak Search is enabled" do
169
+ before {
170
+ subject.should_receive(:get).with(200, uri).once.and_return(:headers => {'link' => ['</riak>; rel="riak_kv_wm_link_walker",</mapred>; rel="riak_kv_wm_mapred",</ping>; rel="riak_kv_wm_ping",</riak>; rel="riak_kv_wm_raw",</stats>; rel="riak_kv_wm_stats", </solr>; rel="riak_solr_indexer_wm", </solr>; rel="riak_solr_searcher_wm"']})
171
+ }
172
+
173
+ it "should generate a search path for the default index" do
174
+ url = subject.solr_select_path(nil, 'a:b')
175
+ url.should be_kind_of(URI)
176
+ url.path.should == '/solr/select'
177
+ url.query.should include("q=a%3Ab")
178
+ url.query.should include('wt=json')
179
+ end
180
+
181
+ it "should generate a search path for a specified index" do
182
+ url = subject.solr_select_path('foo', 'a:b', 'wt' => 'xml')
183
+ url.should be_kind_of(URI)
184
+ url.path.should == '/solr/foo/select'
185
+ url.query.should include("q=a%3Ab")
186
+ url.query.should include('wt=xml')
187
+ end
188
+
189
+ it "should generate an indexing path for the default index" do
190
+ url = subject.solr_update_path(nil)
191
+ url.should be_kind_of(URI)
192
+ url.path.should == '/solr/update'
193
+ end
194
+
195
+ it "should generate an indexing path for a specified index" do
196
+ url = subject.solr_update_path('foo')
197
+ url.should be_kind_of(URI)
198
+ url.path.should == '/solr/foo/update'
199
+ end
200
+ end
26
201
  end
27
202
 
28
203
  {
@@ -31,16 +206,18 @@ describe Riak::Client::HTTPBackend::Configuration do
31
206
  :riak_kv_wm_mapred => :mapred
32
207
  }.each do |resource, alternate|
33
208
  it "should detect the #{resource} resource from the configuration URL" do
34
- @backend.should_receive(:get).with(200, "/", {}, {}).and_return(:headers => {'link' => [%Q{</path>; rel="#{resource}"}]})
35
- @backend.send(resource).should == "/path"
209
+ subject.should_receive(:get).with(200, uri).and_return(:headers => {'link' => [%Q{</path>; rel="#{resource}"}]})
210
+ subject.send(resource).should == "/path"
36
211
  end
37
- it "should fallback to client.#{alternate} if the #{resource} resource is not found" do
38
- @backend.should_receive(:get).with(200, "/", {}, {}).and_return(:headers => {'link' => ['</>; rel="top"']})
39
- @backend.send(resource).should == @client.send(alternate)
212
+
213
+ it "should fallback to client.http_paths[:#{alternate}] if the #{resource} resource is not found" do
214
+ subject.should_receive(:get).with(200, uri).and_return(:headers => {'link' => ['</>; rel="top"']})
215
+ subject.send(resource).should == client.http_paths[alternate]
40
216
  end
41
- it "should fallback to client.#{alternate} if request fails" do
42
- @backend.should_receive(:get).with(200, "/", {}, {}).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 404, {}, ""))
43
- @backend.send(resource).should == @client.send(alternate)
217
+
218
+ it "should fallback to client.http_paths[:#{alternate}] if request fails" do
219
+ subject.should_receive(:get).with(200, uri).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 404, {}, ""))
220
+ subject.send(resource).should == client.http_paths[alternate]
44
221
  end
45
222
  end
46
223
 
@@ -49,16 +226,16 @@ describe Riak::Client::HTTPBackend::Configuration do
49
226
  :riak_kv_wm_stats => "/stats"
50
227
  }.each do |resource, default|
51
228
  it "should detect the #{resource} resource from the configuration URL" do
52
- @backend.should_receive(:get).with(200, "/", {}, {}).and_return(:headers => {'link' => [%Q{</path>; rel="#{resource}"}]})
53
- @backend.send(resource).should == "/path"
229
+ subject.should_receive(:get).with(200, uri).and_return(:headers => {'link' => [%Q{</path>; rel="#{resource}"}]})
230
+ subject.send(resource).should == "/path"
54
231
  end
55
232
  it "should fallback to #{default.inspect} if the #{resource} resource is not found" do
56
- @backend.should_receive(:get).with(200, "/", {}, {}).and_return(:headers => {'link' => ['</>; rel="top"']})
57
- @backend.send(resource).should == default
233
+ subject.should_receive(:get).with(200, uri).and_return(:headers => {'link' => ['</>; rel="top"']})
234
+ subject.send(resource).should == default
58
235
  end
59
236
  it "should fallback to #{default.inspect} if request fails" do
60
- @backend.should_receive(:get).with(200, "/", {}, {}).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 404, {}, ""))
61
- @backend.send(resource).should == default
237
+ subject.should_receive(:get).with(200, uri).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 404, {}, ""))
238
+ subject.send(resource).should == default
62
239
  end
63
240
  end
64
241
  end