riak-client 0.9.0.beta → 0.9.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|