riak-client 0.9.0.beta → 0.9.0.beta2
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/Gemfile +10 -7
- data/Rakefile +21 -3
- data/erl_src/riak_kv_test_backend.beam +0 -0
- data/erl_src/riak_kv_test_backend.erl +29 -13
- data/lib/riak/bucket.rb +1 -1
- data/lib/riak/cache_store.rb +1 -1
- data/lib/riak/client.rb +119 -8
- data/lib/riak/client/beefcake/messages.rb +162 -0
- data/lib/riak/client/beefcake/object_methods.rb +92 -0
- data/lib/riak/client/beefcake_protobuffs_backend.rb +186 -0
- data/lib/riak/client/curb_backend.rb +10 -16
- data/lib/riak/client/excon_backend.rb +14 -18
- data/lib/riak/client/http_backend.rb +13 -13
- data/lib/riak/client/http_backend/object_methods.rb +1 -1
- data/lib/riak/client/http_backend/transport_methods.rb +6 -2
- data/lib/riak/client/net_http_backend.rb +33 -20
- data/lib/riak/client/protobuffs_backend.rb +103 -0
- data/lib/riak/client/pump.rb +44 -0
- data/lib/riak/failed_request.rb +58 -3
- data/lib/riak/locale/en.yml +11 -3
- data/lib/riak/map_reduce.rb +15 -6
- data/lib/riak/map_reduce/filter_builder.rb +4 -4
- data/lib/riak/test_server.rb +5 -1
- data/lib/riak/util/multipart.rb +30 -16
- data/lib/riak/util/multipart/stream_parser.rb +74 -0
- data/riak-client.gemspec +14 -12
- data/spec/fixtures/server.cert.crt +15 -0
- data/spec/fixtures/server.cert.key +15 -0
- data/spec/fixtures/test.pem +1 -0
- data/spec/integration/riak/http_backends_spec.rb +45 -0
- data/spec/integration/riak/protobuffs_backends_spec.rb +45 -0
- data/spec/integration/riak/test_server_spec.rb +2 -2
- data/spec/riak/bucket_spec.rb +4 -4
- data/spec/riak/client_spec.rb +209 -3
- data/spec/riak/excon_backend_spec.rb +8 -7
- data/spec/riak/http_backend/configuration_spec.rb +64 -0
- data/spec/riak/http_backend/object_methods_spec.rb +1 -1
- data/spec/riak/http_backend/transport_methods_spec.rb +129 -0
- data/spec/riak/http_backend_spec.rb +13 -1
- data/spec/riak/map_reduce/filter_builder_spec.rb +45 -0
- data/spec/riak/map_reduce/phase_spec.rb +149 -0
- data/spec/riak/map_reduce_spec.rb +5 -5
- data/spec/riak/net_http_backend_spec.rb +1 -0
- data/spec/riak/{object_spec.rb → robject_spec.rb} +1 -1
- data/spec/riak/stream_parser_spec.rb +66 -0
- data/spec/support/drb_mock_server.rb +2 -2
- data/spec/support/http_backend_implementation_examples.rb +27 -0
- data/spec/support/mock_server.rb +22 -1
- data/spec/support/unified_backend_examples.rb +255 -0
- metadata +43 -54
@@ -23,14 +23,14 @@ else
|
|
23
23
|
|
24
24
|
describe Riak::Client::ExconBackend do
|
25
25
|
def setup_http_mock(method, uri, options={})
|
26
|
-
method
|
27
|
-
uri
|
28
|
-
path
|
29
|
-
query
|
30
|
-
|
31
|
-
body = options[:body] || []
|
26
|
+
method = method.to_s.upcase
|
27
|
+
uri = URI.parse(uri)
|
28
|
+
path = uri.path || "/"
|
29
|
+
query = uri.query || ""
|
30
|
+
body = options[:body] || []
|
32
31
|
headers = options[:headers] || {}
|
33
|
-
headers['Content-Type']
|
32
|
+
headers['Content-Type'] ||= "text/plain"
|
33
|
+
status = options[:status] ? Array(options[:status]).first.to_i : 200
|
34
34
|
@_mock_set = [status, headers, method, path, query, body]
|
35
35
|
$mock_server.expect(*@_mock_set)
|
36
36
|
end
|
@@ -73,4 +73,5 @@ else
|
|
73
73
|
end.should_not raise_error
|
74
74
|
end
|
75
75
|
end
|
76
|
+
|
76
77
|
end
|
@@ -0,0 +1,64 @@
|
|
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::HTTPBackend::Configuration do
|
17
|
+
before do
|
18
|
+
@client = Riak::Client.new
|
19
|
+
@backend = Riak::Client::HTTPBackend.new(@client)
|
20
|
+
end
|
21
|
+
|
22
|
+
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"
|
26
|
+
end
|
27
|
+
|
28
|
+
{
|
29
|
+
:riak_kv_wm_raw => :prefix,
|
30
|
+
:riak_kv_wm_link_walker => :prefix,
|
31
|
+
:riak_kv_wm_mapred => :mapred
|
32
|
+
}.each do |resource, alternate|
|
33
|
+
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"
|
36
|
+
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)
|
40
|
+
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)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
{
|
48
|
+
:riak_kv_wm_ping => "/ping",
|
49
|
+
:riak_kv_wm_stats => "/stats"
|
50
|
+
}.each do |resource, default|
|
51
|
+
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"
|
54
|
+
end
|
55
|
+
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
|
58
|
+
end
|
59
|
+
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
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -84,7 +84,7 @@ describe Riak::Client::HTTPBackend::ObjectMethods do
|
|
84
84
|
end
|
85
85
|
|
86
86
|
it "should parse and escape the location header into the key when present" do
|
87
|
-
@backend.load_object(@object, {:headers => {"content-type" => ["application/json"], "location" => ["/riak/foo/%5Bbaz%5D"]}})
|
87
|
+
@backend.load_object(@object, {:headers => {"content-type" => ["application/json"], "location" => ["/riak/foo/%5Bbaz%5D?vtag=1234"]}})
|
88
88
|
@object.key.should == "[baz]"
|
89
89
|
end
|
90
90
|
|
@@ -0,0 +1,129 @@
|
|
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::HTTPBackend::TransportMethods do
|
17
|
+
before :each do
|
18
|
+
@client = Riak::Client.new
|
19
|
+
@backend = Riak::Client::HTTPBackend.new(@client)
|
20
|
+
@backend.instance_variable_set(:@server_config, {})
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should generate default headers for requests based on the client settings" do
|
24
|
+
@client.client_id = "testing"
|
25
|
+
@backend.default_headers.should == {"X-Riak-ClientId" => "testing", "Accept" => "multipart/mixed, application/json;q=0.7, */*;q=0.5"}
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should generate a root URI based on the client settings" do
|
29
|
+
@backend.root_uri.should be_kind_of(URI)
|
30
|
+
@backend.root_uri.to_s.should == "http://127.0.0.1:8098"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should compute a URI from a relative resource path" do
|
34
|
+
@backend.path("baz").should be_kind_of(URI)
|
35
|
+
@backend.path("foo").to_s.should == "http://127.0.0.1:8098/foo"
|
36
|
+
@backend.path("foo", "bar").to_s.should == "http://127.0.0.1:8098/foo/bar"
|
37
|
+
@backend.path("/foo/bar").to_s.should == "http://127.0.0.1:8098/foo/bar"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should compute a URI from a relative resource path with a hash of query parameters" do
|
41
|
+
@backend.path("baz", :r => 2).to_s.should == "http://127.0.0.1:8098/baz?r=2"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should raise an error if a resource path is too short" do
|
45
|
+
lambda { @backend.verify_path!(["/riak/"]) }.should raise_error(ArgumentError)
|
46
|
+
lambda { @backend.verify_path!(["/riak/", "foo"]) }.should_not raise_error
|
47
|
+
lambda { @backend.verify_path!(["/mapred"]) }.should_not raise_error
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "verify_path_and_body!" do
|
51
|
+
it "should separate the path and body from given arguments" do
|
52
|
+
uri, data = @backend.verify_path_and_body!(["/riak/", "foo", "This is the body."])
|
53
|
+
uri.should == ["/riak/", "foo"]
|
54
|
+
data.should == "This is the body."
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should raise an error if the body is not a string or IO" do
|
58
|
+
lambda { @backend.verify_path_and_body!(["/riak/", "foo", nil]) }.should raise_error(ArgumentError)
|
59
|
+
lambda { @backend.verify_path_and_body!(["/riak/", "foo", File.open("spec/fixtures/cat.jpg")]) }.should_not raise_error(ArgumentError)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should raise an error if a body is not given" do
|
63
|
+
lambda { @backend.verify_path_and_body!(["/riak/", "foo"])}.should raise_error(ArgumentError)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should raise an error if a path is not given" do
|
67
|
+
lambda { @backend.verify_path_and_body!(["/riak/"])}.should raise_error(ArgumentError)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "detecting valid response codes" do
|
72
|
+
it "should accept strings or integers for either argument" do
|
73
|
+
@backend.should be_valid_response("300", "300")
|
74
|
+
@backend.should be_valid_response(300, "300")
|
75
|
+
@backend.should be_valid_response("300", 300)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should accept an array of strings or integers for the expected code" do
|
79
|
+
@backend.should be_valid_response([200,304], "200")
|
80
|
+
@backend.should be_valid_response(["200",304], "200")
|
81
|
+
@backend.should be_valid_response([200,"304"], "200")
|
82
|
+
@backend.should be_valid_response(["200","304"], "200")
|
83
|
+
@backend.should be_valid_response([200,304], 200)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should be false when none of the response codes match" do
|
87
|
+
@backend.should_not be_valid_response(200, 404)
|
88
|
+
@backend.should_not be_valid_response(["200","304"], 404)
|
89
|
+
@backend.should_not be_valid_response([200,304], 404)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "detecting whether a body should be returned" do
|
94
|
+
it "should be false when the method is :head" do
|
95
|
+
@backend.should_not be_return_body(:head, 200, false)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should be false when the response code is 204, 205, or 304" do
|
99
|
+
@backend.should_not be_return_body(:get, 204, false)
|
100
|
+
@backend.should_not be_return_body(:get, 205, false)
|
101
|
+
@backend.should_not be_return_body(:get, 304, false)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should be false when a streaming block was passed" do
|
105
|
+
@backend.should_not be_return_body(:get, 200, true)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should be true when the method is not head, a code other than 204, 205, or 304 was given, and there was no streaming block" do
|
109
|
+
[:get, :put, :post, :delete].each do |method|
|
110
|
+
[100,101,200,201,202,203,206,300,301,302,303,305,307,400,401,
|
111
|
+
402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,
|
112
|
+
500,501,502,503,504,505].each do |code|
|
113
|
+
@backend.should be_return_body(method, code, false)
|
114
|
+
@backend.should be_return_body(method, code.to_s, false)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should force subclasses to implement the perform method" do
|
121
|
+
lambda { @backend.send(:perform, :get, "/foo", {}, 200) }.should raise_error(NotImplementedError)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should allow using the https protocol" do
|
125
|
+
@client = Riak::Client.new(:protocol => 'https')
|
126
|
+
@backend = Riak::Client::HTTPBackend.new(@client)
|
127
|
+
@backend.root_uri.to_s.should eq("https://127.0.0.1:8098")
|
128
|
+
end
|
129
|
+
end
|
@@ -76,7 +76,7 @@ describe Riak::Client::HTTPBackend do
|
|
76
76
|
end
|
77
77
|
|
78
78
|
it "should raise an exception when the response code is not 200 or 304" do
|
79
|
-
@backend.should_receive(:get).and_raise(Riak::
|
79
|
+
@backend.should_receive(:get).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 500, {}, ''))
|
80
80
|
lambda { @backend.reload_object(@object) }.should raise_error(Riak::FailedRequest)
|
81
81
|
end
|
82
82
|
|
@@ -227,6 +227,18 @@ describe Riak::Client::HTTPBackend do
|
|
227
227
|
@backend.stub!(:post).and_return(response)
|
228
228
|
@backend.mapred(@mr).should == response
|
229
229
|
end
|
230
|
+
|
231
|
+
it "should stream results through the block" do
|
232
|
+
data = File.read("spec/fixtures/multipart-mapreduce.txt")
|
233
|
+
@backend.should_receive(:post).with(200, "/mapred", {:chunked => true}, @mr.to_json, hash_including("Content-Type" => "application/json")).and_yield(data)
|
234
|
+
block = mock
|
235
|
+
block.should_receive(:ping).twice.and_return(true)
|
236
|
+
@backend.mapred(@mr) do |phase, data|
|
237
|
+
block.ping
|
238
|
+
phase.should == 0
|
239
|
+
data.should have(1).item
|
240
|
+
end
|
241
|
+
end
|
230
242
|
end
|
231
243
|
|
232
244
|
context "getting statistics" do
|
@@ -0,0 +1,45 @@
|
|
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::MapReduce::FilterBuilder do
|
17
|
+
subject { Riak::MapReduce::FilterBuilder.new }
|
18
|
+
it "should evaluate the passed block on initialization" do
|
19
|
+
subject.class.new do
|
20
|
+
matches "foo"
|
21
|
+
end.to_a.should == [[:matches, "foo"]]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should add filters to the list" do
|
25
|
+
subject.to_lower
|
26
|
+
subject.similar_to("ripple", 3)
|
27
|
+
subject.to_a.should == [[:to_lower],[:similar_to, "ripple", 3]]
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should add a logical operation with a block" do
|
31
|
+
subject.OR do
|
32
|
+
starts_with "foo"
|
33
|
+
ends_with "bar"
|
34
|
+
end
|
35
|
+
subject.to_a.should == [[:or, [[:starts_with, "foo"],[:ends_with, "bar"]]]]
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should raise an error on a filter arity mismatch" do
|
39
|
+
lambda { subject.less_than }.should raise_error(ArgumentError)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should raise an error when a block is not given to a logical operation" do
|
43
|
+
lambda { subject._or }.should raise_error(ArgumentError)
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,149 @@
|
|
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::MapReduce::Phase do
|
17
|
+
before :each do
|
18
|
+
@fun = "function(v,_,_){ return v['values'][0]['data']; }"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should initialize with a type and a function" do
|
22
|
+
phase = Riak::MapReduce::Phase.new(:type => :map, :function => @fun, :language => "javascript")
|
23
|
+
phase.type.should == :map
|
24
|
+
phase.function.should == @fun
|
25
|
+
phase.language.should == "javascript"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should initialize with a type and an MF" do
|
29
|
+
phase = Riak::MapReduce::Phase.new(:type => :map, :function => ["module", "function"], :language => "erlang")
|
30
|
+
phase.type.should == :map
|
31
|
+
phase.function.should == ["module", "function"]
|
32
|
+
phase.language.should == "erlang"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should initialize with a type and a bucket/key" do
|
36
|
+
phase = Riak::MapReduce::Phase.new(:type => :map, :function => {:bucket => "funs", :key => "awesome_map"}, :language => "javascript")
|
37
|
+
phase.type.should == :map
|
38
|
+
phase.function.should == {:bucket => "funs", :key => "awesome_map"}
|
39
|
+
phase.language.should == "javascript"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should assume the language is erlang when the function is an array" do
|
43
|
+
phase = Riak::MapReduce::Phase.new(:type => :map, :function => ["module", "function"])
|
44
|
+
phase.language.should == "erlang"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should assume the language is javascript when the function is a string" do
|
48
|
+
phase = Riak::MapReduce::Phase.new(:type => :map, :function => @fun)
|
49
|
+
phase.language.should == "javascript"
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should assume the language is javascript when the function is a hash" do
|
53
|
+
phase = Riak::MapReduce::Phase.new(:type => :map, :function => {:bucket => "jobs", :key => "awesome_map"})
|
54
|
+
phase.language.should == "javascript"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should accept a WalkSpec for the function when a link phase" do
|
58
|
+
phase = Riak::MapReduce::Phase.new(:type => :link, :function => Riak::WalkSpec.new({}))
|
59
|
+
phase.function.should be_kind_of(Riak::WalkSpec)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should raise an error if a WalkSpec is given for a phase type other than :link" do
|
63
|
+
lambda { Riak::MapReduce::Phase.new(:type => :map, :function => Riak::WalkSpec.new({})) }.should raise_error(ArgumentError)
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "converting to JSON for the job" do
|
67
|
+
before :each do
|
68
|
+
@phase = Riak::MapReduce::Phase.new(:type => :map, :function => "")
|
69
|
+
end
|
70
|
+
|
71
|
+
[:map, :reduce].each do |type|
|
72
|
+
describe "when a #{type} phase" do
|
73
|
+
before :each do
|
74
|
+
@phase.type = type
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should be an object with a single key of '#{type}'" do
|
78
|
+
@phase.to_json.should =~ /^\{"#{type}":/
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should include the language" do
|
82
|
+
@phase.to_json.should =~ /"language":/
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should include the keep value" do
|
86
|
+
@phase.to_json.should =~ /"keep":false/
|
87
|
+
@phase.keep = true
|
88
|
+
@phase.to_json.should =~ /"keep":true/
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should include the function source when the function is a source string" do
|
92
|
+
@phase.function = "function(v,_,_){ return v; }"
|
93
|
+
@phase.to_json.should include(@phase.function)
|
94
|
+
@phase.to_json.should =~ /"source":/
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should include the function name when the function is not a lambda" do
|
98
|
+
@phase.function = "Riak.mapValues"
|
99
|
+
@phase.to_json.should include('"name":"Riak.mapValues"')
|
100
|
+
@phase.to_json.should_not include('"source"')
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should include the bucket and key when referring to a stored function" do
|
104
|
+
@phase.function = {:bucket => "design", :key => "wordcount_map"}
|
105
|
+
@phase.to_json.should include('"bucket":"design"')
|
106
|
+
@phase.to_json.should include('"key":"wordcount_map"')
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should include the module and function when invoking an Erlang function" do
|
110
|
+
@phase.function = ["riak_mapreduce", "mapreduce_fun"]
|
111
|
+
@phase.to_json.should include('"module":"riak_mapreduce"')
|
112
|
+
@phase.to_json.should include('"function":"mapreduce_fun"')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "when a link phase" do
|
118
|
+
before :each do
|
119
|
+
@phase.type = :link
|
120
|
+
@phase.function = {}
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should be an object of a single key 'link'" do
|
124
|
+
@phase.to_json.should =~ /^\{"link":/
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should include the bucket" do
|
128
|
+
@phase.to_json.should =~ /"bucket":"_"/
|
129
|
+
@phase.function[:bucket] = "foo"
|
130
|
+
@phase.to_json.should =~ /"bucket":"foo"/
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should include the tag" do
|
134
|
+
@phase.to_json.should =~ /"tag":"_"/
|
135
|
+
@phase.function[:tag] = "parent"
|
136
|
+
@phase.to_json.should =~ /"tag":"parent"/
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should include the keep value" do
|
140
|
+
@phase.to_json.should =~ /"keep":false/
|
141
|
+
@phase.keep = true
|
142
|
+
@phase.to_json.should =~ /"keep":true/
|
143
|
+
@phase.keep = false
|
144
|
+
@phase.function[:keep] = true
|
145
|
+
@phase.to_json.should =~ /"keep":true/
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|