Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

First pass at unified backend integration specs, fixing some oversigh…

…ts in existing specs.
  • Loading branch information...
commit e085ef266de0aa48e88c27d0bee3ce3b8b3a979c 1 parent d5c3403
@seancribbs seancribbs authored
View
1  riak-client/.rspec
@@ -1 +1,2 @@
--color
+--fail-fast
View
1  riak-client/lib/riak/client.rb
@@ -14,6 +14,7 @@
require 'riak'
require 'tempfile'
require 'delegate'
+require 'riak/failed_request'
module Riak
# A client connection to Riak.
View
2  riak-client/lib/riak/client/net_http_backend.rb
@@ -48,7 +48,7 @@ def perform(method, uri, headers, expect, data=nil) #:nodoc:
if return_body?(method, response.code, block_given?)
result[:body] = response.body
else
- raise HTTPFailedRequest.new(method, expect, response.code.to_i, response.to_hash, response.body)
+ raise Riak::HTTPFailedRequest.new(method, expect, response.code.to_i, response.to_hash, response.body)
end
end
end
View
8 riak-client/lib/riak/client/pump.rb
@@ -25,15 +25,15 @@ class Pump
def initialize(block)
@fiber = Fiber.new do
loop do
- block.call *Fiber.yield
+ block.call Fiber.yield
end
end
@fiber.resume
end
- def pump(*input)
- @fiber.resume *input
- input.first.size if input.size == 1 # For curb
+ def pump(input)
+ @fiber.resume input
+ input.size if input.respond_to?(:size) # for curb
end
def to_proc
View
3  riak-client/lib/riak/util/multipart/stream_parser.rb
@@ -45,8 +45,7 @@ def accept(chunk)
# Returns a Proc that can be passed to an HTTP request method.
def to_proc
- parser = self
- Proc.new {|chunk| parser.accept(chunk) }
+ method(:accept).to_proc
end
private
View
45 riak-client/spec/integration/riak/http_backends_spec.rb
@@ -0,0 +1,45 @@
+# Copyright 2010 Sean Cribbs and Basho Technologies, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+require File.expand_path("../../spec_helper", File.dirname(__FILE__))
+
+describe "HTTP" do
+ before :all do
+ if $test_server
+ @web_port = 9000
+ $test_server.start
+ end
+ end
+
+ before do
+ @web_port ||= 8098
+ @client = Riak::Client.new(:port => @web_port)
+ end
+
+ after do
+ $test_server.recycle if $test_server.started?
+ end
+
+ [:CurbBackend, :ExconBackend, :NetHTTPBackend].each do |klass|
+ bklass = Riak::Client.const_get(klass)
+ if bklass.configured?
+ describe klass.to_s do
+ before do
+ @backend = bklass.new(@client)
+ end
+
+ it_should_behave_like "Unified backend API"
+ end
+ end
+ end
+end
View
8 riak-client/spec/riak/bucket_spec.rb
@@ -120,15 +120,15 @@
end
it "should create a new blank object if the key does not exist" do
- @backend.should_receive(:fetch_object).and_raise(Riak::FailedRequest.new(:get, 200, 404, {}, "File not found"))
+ @backend.should_receive(:fetch_object).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 404, {}, "File not found"))
obj = @bucket.get_or_new('db')
obj.key.should == 'db'
obj.data.should be_blank
end
it "should bubble up non-ok non-missing errors" do
- @backend.should_receive(:fetch_object).and_raise(Riak::FailedRequest.new(:get, 200, 500, {}, "File not found"))
- lambda { @bucket.get_or_new('db') }.should raise_error(Riak::FailedRequest)
+ @backend.should_receive(:fetch_object).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 500, {}, "File not found"))
+ lambda { @bucket.get_or_new('db') }.should raise_error(Riak::HTTPFailedRequest)
end
it "should pass along the given R quorum parameter" do
@@ -192,7 +192,7 @@
end
it "should return false if the object doesn't exist" do
- @backend.should_receive(:fetch_object).and_raise(Riak::FailedRequest.new(:get, [200,300], 404, {}, "not found"))
+ @backend.should_receive(:fetch_object).and_raise(Riak::HTTPFailedRequest.new(:get, [200,300], 404, {}, "not found"))
@bucket.exists?("foo").should be_false
end
end
View
4 riak-client/spec/riak/http_backend/configuration_spec.rb
@@ -39,7 +39,7 @@
@backend.send(resource).should == @client.send(alternate)
end
it "should fallback to client.#{alternate} if request fails" do
- @backend.should_receive(:get).with(200, "/", {}, {}).and_raise(Riak::FailedRequest.new(:get, 200, 404, {}, ""))
+ @backend.should_receive(:get).with(200, "/", {}, {}).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 404, {}, ""))
@backend.send(resource).should == @client.send(alternate)
end
end
@@ -57,7 +57,7 @@
@backend.send(resource).should == default
end
it "should fallback to #{default.inspect} if request fails" do
- @backend.should_receive(:get).with(200, "/", {}, {}).and_raise(Riak::FailedRequest.new(:get, 200, 404, {}, ""))
+ @backend.should_receive(:get).with(200, "/", {}, {}).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 404, {}, ""))
@backend.send(resource).should == default
end
end
View
2  riak-client/spec/riak/http_backend_spec.rb
@@ -76,7 +76,7 @@
end
it "should raise an exception when the response code is not 200 or 304" do
- @backend.should_receive(:get).and_raise(Riak::FailedRequest.new(:get, 200, 500, {}, ''))
+ @backend.should_receive(:get).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 500, {}, ''))
lambda { @backend.reload_object(@object) }.should raise_error(Riak::FailedRequest)
end
View
4 riak-client/spec/riak/map_reduce_spec.rb
@@ -250,7 +250,7 @@
end
it "should interpret failed requests with JSON content-types as map reduce errors" do
- @backend.stub!(:mapred).and_raise(Riak::FailedRequest.new(:post, 200, 500, {"content-type" => ["application/json"]}, '{"error":"syntax error"}'))
+ @backend.stub!(:mapred).and_raise(Riak::HTTPFailedRequest.new(:post, 200, 500, {"content-type" => ["application/json"]}, '{"error":"syntax error"}'))
lambda { @mr.run }.should raise_error(Riak::MapReduceError)
begin
@mr.run
@@ -262,7 +262,7 @@
end
it "should re-raise non-JSON error responses" do
- @backend.stub!(:mapred).and_raise(Riak::FailedRequest.new(:post, 200, 500, {"content-type" => ["text/plain"]}, 'Oops, you bwoke it.'))
+ @backend.stub!(:mapred).and_raise(Riak::HTTPFailedRequest.new(:post, 200, 500, {"content-type" => ["text/plain"]}, 'Oops, you bwoke it.'))
lambda { @mr.run }.should raise_error(Riak::FailedRequest)
end
end
View
2  riak-client/spec/riak/robject_spec.rb
@@ -374,7 +374,7 @@
end
it "should pass through a failed request exception" do
- @backend.should_receive(:delete_object).and_raise(Riak::FailedRequest.new(:delete, [204,404], 500, {}, ""))
+ @backend.should_receive(:delete_object).and_raise(Riak::HTTPFailedRequest.new(:delete, [204,404], 500, {}, ""))
lambda { @object.delete }.should raise_error(Riak::FailedRequest)
end
end
View
255 riak-client/spec/support/unified_backend_examples.rb
@@ -0,0 +1,255 @@
+# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+shared_examples_for "Unified backend API" do
+ # ping
+ it "should ping the server" do
+ @backend.ping.should be_true
+ end
+
+ # fetch_object
+ context "fetching an object" do
+ before do
+ @robject = Riak::RObject.new(@client.bucket("test"), "fetch")
+ @robject.content_type = "application/json"
+ @robject.data = { "test" => "pass" }
+ @backend.store_object(@robject)
+ end
+
+ it "should find a stored object" do
+ robj = @backend.fetch_object("test", "fetch")
+ robj.should be_kind_of(Riak::RObject)
+ robj.data.should == { "test" => "pass" }
+ end
+
+ it "should raise an error when the object is not found" do
+ begin
+ @backend.fetch_object("test", "notfound")
+ rescue Riak::FailedRequest => exception
+ @exception = exception
+ end
+ @exception.should be_kind_of(Riak::FailedRequest)
+ @exception.should be_not_found
+ end
+
+ [1,2,3,:one,:quorum,:all,:default].each do |q|
+ it "should accept a R value of #{q.inspect} for the request" do
+ robj = @backend.fetch_object("test", "fetch", q)
+ robj.should be_kind_of(Riak::RObject)
+ robj.data.should == { "test" => "pass" }
+ end
+ end
+ end
+
+ # reload_object
+ context "reloading an existing object" do
+ before do
+ @robject = Riak::RObject.new(@client.bucket('test'), 'reload')
+ @robject.content_type = "application/json"
+ @robject.data = {"test" => "pass"}
+ @backend.store_object(@robject)
+ @robject2 = @backend.fetch_object("test", "reload")
+ @robject2.data["test"] = "second"
+ @backend.store_object(@robject2, true)
+ end
+
+ it "should modify the object with the reloaded data" do
+ @backend.reload_object(@robject)
+ end
+
+ [1,2,3,:one,:quorum,:all,:default].each do |q|
+ it "should accept a valid R value of #{q.inspect} for the request" do
+ @backend.reload_object(@robject, q)
+ end
+ end
+
+ after do
+ @robject.vclock.should == @robject2.vclock
+ @robject.data['test'].should == "second"
+ end
+ end
+
+ # store_object
+ context "storing an object" do
+ before do
+ @robject = Riak::RObject.new(@client.bucket('test'), 'store')
+ @robject.content_type = "application/json"
+ @robject.data = {"test" => "pass"}
+ end
+
+ it "should save the object" do
+ @backend.store_object(@robject)
+ end
+
+ it "should modify the object with the returned data if returnbody" do
+ @backend.store_object(@robject, true)
+ @robject.vclock.should be_present
+ end
+
+ [1,2,3,:one,:quorum,:all,:default].each do |q|
+ it "should accept a W value of #{q.inspect} for the request" do
+ @backend.store_object(@robject, false, q)
+ @client.bucket("test").exists?("store").should be_true
+ end
+
+ it "should accept a DW value of #{q.inspect} for the request" do
+ @backend.store_object(@robject, false, nil, q)
+ end
+ end
+
+ after do
+ @client.bucket("test").exists?("store").should be_true
+ end
+ end
+
+ # delete_object
+ context "deleting an object" do
+ before do
+ @obj = Riak::RObject.new(@client.bucket("test"), "delete")
+ @obj.content_type = "application/json"
+ @obj.data = [1]
+ @backend.store_object(@obj)
+ end
+
+ it "should remove the object" do
+ @backend.delete_object("test", "delete")
+ @obj.bucket.exists?("delete").should be_false
+ end
+
+ [1,2,3,:one,:quorum,:all,:default].each do |q|
+ it "should accept an RW value of #{q.inspect} for the request" do
+ @backend.delete_object("test", "delete", q)
+ end
+ end
+
+ after do
+ @obj.bucket.exists?("delete").should be_false
+ end
+ end
+
+ # get_bucket_props
+ context "fetching bucket properties" do
+ it "should fetch a hash of bucket properties" do
+ props = @backend.get_bucket_props("test")
+ props.should be_kind_of(Hash)
+ props.should include("n_val")
+ end
+ end
+
+ # set_bucket_props
+ context "setting bucket properties" do
+ it "should store properties for the bucket" do
+ @backend.set_bucket_props("test", {"rw" => "quorum"})
+ @backend.get_bucket_props("test")['rw'].should == "quorum"
+ end
+ end
+
+ # list_keys
+ context "listing keys in a bucket" do
+ before do
+ obj = Riak::RObject.new(@client.bucket("test"), "keys")
+ obj.content_type = "application/json"
+ obj.data = [1]
+ @backend.store_object(obj)
+ end
+
+ it "should fetch an array of string keys" do
+ @backend.list_keys("test").should == ["keys"]
+ end
+
+ context "streaming through a block" do
+ it "should pass an array of keys to the block" do
+ @backend.list_keys("test") do |keys|
+ keys.should == ["keys"] unless keys.empty?
+ end
+ end
+
+ it "should allow requests issued inside the block to execute" do
+ errors = []
+ @backend.list_keys("test") do |keys|
+ keys.each do |key|
+ begin
+ @backend.fetch_object("test", key)
+ rescue => e
+ errors << e
+ end
+ end
+ end
+ errors.should be_empty
+ end
+ end
+ end
+
+ # list_buckets
+ context "listing buckets" do
+ before do
+ obj = Riak::RObject.new(@client.bucket("test"), "buckets")
+ obj.content_type = "application/json"
+ obj.data = [1]
+ @backend.store_object(obj)
+ end
+
+ it "should fetch a list of string bucket names" do
+ list = @backend.list_buckets
+ list.should be_kind_of(Array)
+ list.should include("test")
+ end
+ end
+
+ # mapred
+ context "performing MapReduce" do
+ before do
+ obj = Riak::RObject.new(@client.bucket("test"), "1")
+ obj.content_type = "application/json"
+ obj.data = {"value" => "1" }
+ @backend.store_object(obj)
+ @mapred = Riak::MapReduce.new(@client).add("test").map("Riak.mapValuesJson", :keep => true)
+ end
+
+ it "should perform a simple MapReduce request" do
+ @backend.mapred(@mapred).should == [{"value" => "1"}]
+ end
+
+ context "streaming results through a block" do
+ it "should pass phase number and result to the block" do
+ @backend.mapred(@mapred) do |phase, result|
+ unless result.empty?
+ phase.should == 0
+ result.should == [{"value" => "1"}]
+ end
+ end
+ end
+
+ it "should allow requests issued inside the block to execute" do
+ errors = []
+ @backend.mapred(@mapred) do |phase, result|
+ unless result.empty?
+ result.each do |v|
+ begin
+ @backend.fetch_object("test", v['value'])
+ rescue => e
+ errors << e
+ end
+ end
+ end
+ end
+ errors.should be_empty
+ end
+ end
+ end
+
+ after do
+ $test_server.recycle if $test_server.started?
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.