зеркало из https://github.com/github/aws-s3.git
Port hand rolled mock code over to using flexmock
This commit is contained in:
Родитель
638b144068
Коммит
d9af94a021
|
@ -311,4 +311,4 @@ module AWS
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -23,58 +23,52 @@ class BaseTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_request_tries_again_when_encountering_an_internal_error
|
||||
Bucket.in_test_mode do
|
||||
Bucket.request_returns [
|
||||
# First request is an internal error
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Second request is a success
|
||||
{:body => Fixtures::Buckets.empty_bucket, :code => 200}
|
||||
]
|
||||
bucket = nil # Block scope hack
|
||||
assert_nothing_raised do
|
||||
bucket = Bucket.find('marcel')
|
||||
end
|
||||
# Don't call objects 'cause we don't want to make another request
|
||||
assert bucket.object_cache.empty?
|
||||
end
|
||||
mock_connection_for(Bucket, :returns => [
|
||||
# First request is an internal error
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Second request is a success
|
||||
{:body => Fixtures::Buckets.empty_bucket, :code => 200}
|
||||
])
|
||||
bucket = nil # Block scope hack
|
||||
assert_nothing_raised do
|
||||
bucket = Bucket.find('marcel')
|
||||
end
|
||||
# Don't call objects 'cause we don't want to make another request
|
||||
assert bucket.object_cache.empty?
|
||||
end
|
||||
|
||||
def test_request_tries_up_to_three_times
|
||||
Bucket.in_test_mode do
|
||||
Bucket.request_returns [
|
||||
# First request is an internal error
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Second request is also an internal error
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Ditto third
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Fourth works
|
||||
{:body => Fixtures::Buckets.empty_bucket, :code => 200}
|
||||
]
|
||||
bucket = nil # Block scope hack
|
||||
assert_nothing_raised do
|
||||
bucket = Bucket.find('marcel')
|
||||
end
|
||||
# Don't call objects 'cause we don't want to make another request
|
||||
assert bucket.object_cache.empty?
|
||||
mock_connection_for(Bucket, :returns => [
|
||||
# First request is an internal error
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Second request is also an internal error
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Ditto third
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Fourth works
|
||||
{:body => Fixtures::Buckets.empty_bucket, :code => 200}
|
||||
])
|
||||
bucket = nil # Block scope hack
|
||||
assert_nothing_raised do
|
||||
bucket = Bucket.find('marcel')
|
||||
end
|
||||
# Don't call objects 'cause we don't want to make another request
|
||||
assert bucket.object_cache.empty?
|
||||
end
|
||||
|
||||
def test_request_tries_again_three_times_and_gives_up
|
||||
Bucket.in_test_mode do
|
||||
Bucket.request_returns [
|
||||
# First request is an internal error
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Second request is also an internal error
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Ditto third
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Ditto fourth
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
]
|
||||
assert_raises(InternalError) do
|
||||
Bucket.find('marcel')
|
||||
end
|
||||
mock_connection_for(Bucket, :returns => [
|
||||
# First request is an internal error
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Second request is also an internal error
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Ditto third
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
# Ditto fourth
|
||||
{:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
|
||||
])
|
||||
assert_raises(InternalError) do
|
||||
Bucket.find('marcel')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,30 +15,27 @@ class BucketTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_empty_bucket
|
||||
Bucket.request_always_returns :body => Fixtures::Buckets.empty_bucket, :code => 200 do
|
||||
bucket = Bucket.find('marcel_molina')
|
||||
assert bucket.empty?
|
||||
end
|
||||
mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.empty_bucket, :code => 200})
|
||||
bucket = Bucket.find('marcel_molina')
|
||||
assert bucket.empty?
|
||||
end
|
||||
|
||||
def test_bucket_with_one_file
|
||||
Bucket.request_always_returns :body => Fixtures::Buckets.bucket_with_one_key, :code => 200 do
|
||||
bucket = Bucket.find('marcel_molina')
|
||||
assert !bucket.empty?
|
||||
assert_equal 1, bucket.size
|
||||
assert_equal %w(tongue_overload.jpg), bucket.objects.map {|object| object.key}
|
||||
assert bucket['tongue_overload.jpg']
|
||||
end
|
||||
mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_one_key, :code => 200})
|
||||
bucket = Bucket.find('marcel_molina')
|
||||
assert !bucket.empty?
|
||||
assert_equal 1, bucket.size
|
||||
assert_equal %w(tongue_overload.jpg), bucket.objects.map {|object| object.key}
|
||||
assert bucket['tongue_overload.jpg']
|
||||
end
|
||||
|
||||
def test_bucket_with_more_than_one_file
|
||||
Bucket.request_always_returns :body => Fixtures::Buckets.bucket_with_more_than_one_key, :code => 200 do
|
||||
bucket = Bucket.find('marcel_molina')
|
||||
assert !bucket.empty?
|
||||
assert_equal 2, bucket.size
|
||||
assert_equal %w(beluga_baby.jpg tongue_overload.jpg), bucket.objects.map {|object| object.key}.sort
|
||||
assert bucket['tongue_overload.jpg']
|
||||
end
|
||||
mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_more_than_one_key, :code => 200})
|
||||
bucket = Bucket.find('marcel_molina')
|
||||
assert !bucket.empty?
|
||||
assert_equal 2, bucket.size
|
||||
assert_equal %w(beluga_baby.jpg tongue_overload.jpg), bucket.objects.map {|object| object.key}.sort
|
||||
assert bucket['tongue_overload.jpg']
|
||||
end
|
||||
|
||||
def test_bucket_path
|
||||
|
|
|
@ -54,22 +54,20 @@ class ErrorTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_error_response_handles_attributes_with_no_value
|
||||
Bucket.in_test_mode do
|
||||
Bucket.request_returns :body => Fixtures::Errors.error_with_no_message, :code => 500
|
||||
|
||||
begin
|
||||
Bucket.create('foo', 'invalid-argument' => 'bad juju')
|
||||
rescue ResponseError => error
|
||||
end
|
||||
mock_connection_for(Bucket, :returns => {:body => Fixtures::Errors.error_with_no_message, :code => 500})
|
||||
|
||||
assert_nothing_raised do
|
||||
error.response.error.message
|
||||
end
|
||||
assert_nil error.response.error.message
|
||||
|
||||
assert_raises(NoMethodError) do
|
||||
error.response.error.non_existant_method
|
||||
end
|
||||
begin
|
||||
Bucket.create('foo', 'invalid-argument' => 'bad juju')
|
||||
rescue ResponseError => error
|
||||
end
|
||||
|
||||
assert_nothing_raised do
|
||||
error.response.error.message
|
||||
end
|
||||
assert_nil error.response.error.message
|
||||
|
||||
assert_raises(NoMethodError) do
|
||||
error.response.error.non_existant_method
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,17 +1,16 @@
|
|||
module AWS
|
||||
module S3
|
||||
class FakeResponse < String
|
||||
class FakeResponse
|
||||
attr_reader :code, :body, :headers
|
||||
def initialize(options = {})
|
||||
@code = options.delete(:code) || 200
|
||||
@body = options.delete(:body) || ''
|
||||
@headers = {'content-type' => 'application/xml'}.merge(options.delete(:headers) || {})
|
||||
super(@body)
|
||||
end
|
||||
|
||||
# For ErrorResponse
|
||||
def response
|
||||
self
|
||||
body
|
||||
end
|
||||
|
||||
def [](header)
|
||||
|
|
|
@ -7,25 +7,23 @@ class ObjectTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_header_settings_reader_and_writer
|
||||
S3Object.in_test_mode do
|
||||
headers = {'content-type' => 'text/plain'}
|
||||
S3Object.request_returns :headers => headers
|
||||
|
||||
assert_nothing_raised do
|
||||
@object.content_type
|
||||
end
|
||||
headers = {'content-type' => 'text/plain'}
|
||||
mock_connection_for(S3Object, :returns => {:headers => headers})
|
||||
|
||||
assert_equal 'text/plain', @object.content_type
|
||||
|
||||
assert_nothing_raised do
|
||||
@object.content_type = 'image/jpg'
|
||||
end
|
||||
|
||||
assert_equal 'image/jpg', @object.content_type
|
||||
|
||||
assert_raises(NoMethodError) do
|
||||
@object.non_existant_header_setting
|
||||
end
|
||||
assert_nothing_raised do
|
||||
@object.content_type
|
||||
end
|
||||
|
||||
assert_equal 'text/plain', @object.content_type
|
||||
|
||||
assert_nothing_raised do
|
||||
@object.content_type = 'image/jpg'
|
||||
end
|
||||
|
||||
assert_equal 'image/jpg', @object.content_type
|
||||
|
||||
assert_raises(NoMethodError) do
|
||||
@object.non_existant_header_setting
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -75,91 +73,81 @@ class ObjectTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_fetching_object_value_generates_value_object
|
||||
S3Object.in_test_mode do
|
||||
S3Object.request_returns :body => 'hello!'
|
||||
value = S3Object.value('foo', 'bar')
|
||||
assert_kind_of S3Object::Value, value
|
||||
assert_equal 'hello!', value
|
||||
end
|
||||
mock_connection_for(S3Object, :returns => {:body => 'hello!'})
|
||||
value = S3Object.value('foo', 'bar')
|
||||
assert_kind_of S3Object::Value, value
|
||||
assert_equal 'hello!', value
|
||||
end
|
||||
|
||||
def test_fetching_file_by_name_raises_when_heuristic_fails
|
||||
S3Object.request_always_returns :body => Fixtures::Buckets.bucket_with_one_key do
|
||||
assert_raises(NoSuchKey) do
|
||||
S3Object.find('not_tongue_overload.jpg', 'marcel_molina')
|
||||
end
|
||||
|
||||
object = nil # Block scoping
|
||||
assert_nothing_raised do
|
||||
object = S3Object.find('tongue_overload.jpg', 'marcel_molina')
|
||||
end
|
||||
assert_kind_of S3Object, object
|
||||
assert_equal 'tongue_overload.jpg', object.key
|
||||
mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_one_key})
|
||||
assert_raises(NoSuchKey) do
|
||||
S3Object.find('not_tongue_overload.jpg', 'marcel_molina')
|
||||
end
|
||||
|
||||
object = nil # Block scoping
|
||||
assert_nothing_raised do
|
||||
object = S3Object.find('tongue_overload.jpg', 'marcel_molina')
|
||||
end
|
||||
assert_kind_of S3Object, object
|
||||
assert_equal 'tongue_overload.jpg', object.key
|
||||
end
|
||||
|
||||
def test_about
|
||||
S3Object.in_test_mode do
|
||||
headers = {'content-size' => '12345', 'date' => Time.now.httpdate, 'content-type' => 'application/xml'}
|
||||
S3Object.request_returns :headers => headers
|
||||
about = S3Object.about('foo', 'bar')
|
||||
assert_kind_of S3Object::About, about
|
||||
assert_equal headers, about
|
||||
|
||||
S3Object.request_returns :code => 404
|
||||
assert_raises(NoSuchKey) do
|
||||
S3Object.about('foo', 'bar')
|
||||
end
|
||||
headers = {'content-size' => '12345', 'date' => Time.now.httpdate, 'content-type' => 'application/xml'}
|
||||
mock_connection_for(S3Object, :returns => [
|
||||
{:headers => headers},
|
||||
{:code => 404}
|
||||
]
|
||||
)
|
||||
about = S3Object.about('foo', 'bar')
|
||||
assert_kind_of S3Object::About, about
|
||||
assert_equal headers, about
|
||||
|
||||
assert_raises(NoSuchKey) do
|
||||
S3Object.about('foo', 'bar')
|
||||
end
|
||||
end
|
||||
|
||||
def test_exists?
|
||||
S3Object.in_test_mode do
|
||||
S3Object.request_returns :code => 404
|
||||
assert_equal false, S3Object.exists?('foo', 'bar')
|
||||
|
||||
S3Object.request_returns :code => 200
|
||||
assert_equal true, S3Object.exists?('foo', 'bar')
|
||||
end
|
||||
def test_can_tell_that_an_s3object_does_not_exist
|
||||
mock_connection_for(S3Object, :returns => {:code => 404})
|
||||
assert_equal false, S3Object.exists?('foo', 'bar')
|
||||
end
|
||||
|
||||
def test_can_tell_that_an_s3object_exists
|
||||
mock_connection_for(S3Object, :returns => {:code => 200})
|
||||
assert_equal true, S3Object.exists?('foo', 'bar')
|
||||
end
|
||||
|
||||
def test_s3object_equality
|
||||
Bucket.in_test_mode do
|
||||
Bucket.request_returns :body => Fixtures::Buckets.bucket_with_more_than_one_key
|
||||
file1, file2 = Bucket.objects('does not matter')
|
||||
assert file1 == file1
|
||||
assert file2 == file2
|
||||
assert !(file1 == file2) # /!\ Parens required /!\
|
||||
end
|
||||
mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_more_than_one_key})
|
||||
file1, file2 = Bucket.objects('does not matter')
|
||||
assert file1 == file1
|
||||
assert file2 == file2
|
||||
assert !(file1 == file2) # /!\ Parens required /!\
|
||||
end
|
||||
|
||||
def test_inspect
|
||||
S3Object.in_test_mode do
|
||||
S3Object.request_returns :body => Fixtures::Buckets.bucket_with_one_key
|
||||
object = S3Object.find('tongue_overload.jpg', 'bucket does not matter')
|
||||
assert object.path
|
||||
assert_nothing_raised { object.inspect }
|
||||
assert object.inspect[object.path]
|
||||
end
|
||||
end
|
||||
mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_one_key})
|
||||
object = S3Object.find('tongue_overload.jpg', 'bucket does not matter')
|
||||
assert object.path
|
||||
assert_nothing_raised { object.inspect }
|
||||
assert object.inspect[object.path]
|
||||
end
|
||||
|
||||
def test_etag
|
||||
S3Object.in_test_mode do
|
||||
S3Object.request_returns :body => Fixtures::Buckets.bucket_with_one_key
|
||||
def test_etag
|
||||
mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_one_key})
|
||||
file = S3Object.find('tongue_overload.jpg', 'bucket does not matter')
|
||||
assert file.etag
|
||||
assert_equal 'f21f7c4e8ea6e34b268887b07d6da745', file.etag
|
||||
end
|
||||
end
|
||||
|
||||
def test_fetching_information_about_an_object_that_does_not_exist_raises_no_such_key
|
||||
S3Object.in_test_mode do
|
||||
S3Object.request_returns :body => '', :code => 404
|
||||
assert_raises(NoSuchKey) do
|
||||
S3Object.about('asdfasdfasdfas-this-does-not-exist', 'bucket does not matter')
|
||||
end
|
||||
end
|
||||
end
|
||||
def test_fetching_information_about_an_object_that_does_not_exist_raises_no_such_key
|
||||
mock_connection_for(S3Object, :returns => {:body => '', :code => 404})
|
||||
assert_raises(NoSuchKey) do
|
||||
S3Object.about('asdfasdfasdfas-this-does-not-exist', 'bucket does not matter')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class MetadataTest < Test::Unit::TestCase
|
||||
|
|
|
@ -34,11 +34,9 @@ end
|
|||
|
||||
class S3ObjectResponseTest < Test::Unit::TestCase
|
||||
def test_etag_extracted
|
||||
S3Object.in_test_mode do
|
||||
S3Object.request_returns :headers => {"etag"=>"\"acbd18db4cc2f85cedef654fccc4a4d8\""}
|
||||
object_response = S3Object.create('name_does_not_matter', 'data does not matter', 'bucket does not matter')
|
||||
assert_equal "acbd18db4cc2f85cedef654fccc4a4d8", object_response.etag
|
||||
end
|
||||
mock_connection_for(S3Object, :returns => {:headers => {"etag" => %("acbd18db4cc2f85cedef654fccc4a4d8")}}).once
|
||||
object_response = S3Object.create('name_does_not_matter', 'data does not matter', 'bucket does not matter')
|
||||
assert_equal "acbd18db4cc2f85cedef654fccc4a4d8", object_response.etag
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -2,25 +2,22 @@ require File.dirname(__FILE__) + '/test_helper'
|
|||
|
||||
class ServiceTest < Test::Unit::TestCase
|
||||
def test_bucket_list_with_empty_bucket_list
|
||||
Service.request_always_returns :body => Fixtures::Buckets.empty_bucket_list, :code => 200 do
|
||||
list = Service.buckets(:reload)
|
||||
assert_equal [], list
|
||||
end
|
||||
mock_connection_for(Service, :returns => {:body => Fixtures::Buckets.empty_bucket_list, :code => 200})
|
||||
list = Service.buckets(:reload)
|
||||
assert_equal [], list
|
||||
end
|
||||
|
||||
def test_bucket_list_with_bucket_list_containing_one_bucket
|
||||
Service.request_always_returns :body => Fixtures::Buckets.bucket_list_with_one_bucket, :code => 200 do
|
||||
list = Service.buckets(:reload)
|
||||
assert_equal 1, list.size
|
||||
assert_equal 'marcel_molina', list.first.name
|
||||
end
|
||||
mock_connection_for(Service, :returns => {:body => Fixtures::Buckets.bucket_list_with_one_bucket, :code => 200})
|
||||
list = Service.buckets(:reload)
|
||||
assert_equal 1, list.size
|
||||
assert_equal 'marcel_molina', list.first.name
|
||||
end
|
||||
|
||||
def test_bucket_list_with_bucket_list_containing_more_than_one_bucket
|
||||
Service.request_always_returns :body => Fixtures::Buckets.bucket_list_with_more_than_one_bucket, :code => 200 do
|
||||
list = Service.buckets(:reload)
|
||||
assert_equal 2, list.size
|
||||
assert_equal %w(marcel_molina marcel_molina_jr), list.map {|bucket| bucket.name}.sort
|
||||
end
|
||||
mock_connection_for(Service, :returns => {:body => Fixtures::Buckets.bucket_list_with_more_than_one_bucket, :code => 200})
|
||||
list = Service.buckets(:reload)
|
||||
assert_equal 2, list.size
|
||||
assert_equal %w(marcel_molina marcel_molina_jr), list.map {|bucket| bucket.name}.sort
|
||||
end
|
||||
end
|
|
@ -1,9 +1,12 @@
|
|||
require 'test/unit'
|
||||
$:.unshift File.dirname(__FILE__) + '/../lib'
|
||||
require 'aws/s3'
|
||||
require File.dirname(__FILE__) + '/mocks/base'
|
||||
require File.dirname(__FILE__) + '/mocks/fake_response'
|
||||
require File.dirname(__FILE__) + '/fixtures'
|
||||
require_library_or_gem 'breakpoint'
|
||||
require_library_or_gem 'ruby-debug'
|
||||
require_library_or_gem 'flexmock'
|
||||
require_library_or_gem 'flexmock/test_unit'
|
||||
|
||||
|
||||
# Data copied from http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAuthentication.html
|
||||
module AmazonDocExampleData
|
||||
|
@ -83,4 +86,22 @@ class Test::Unit::TestCase
|
|||
def sample_proxy_settings
|
||||
{:host => 'http://google.com', :port => 8080, :user => 'marcel', :password => 'secret'}
|
||||
end
|
||||
|
||||
def mock_connection_for(klass, options = {})
|
||||
data = options[:returns]
|
||||
return_values = case data
|
||||
when Hash
|
||||
FakeResponse.new(data)
|
||||
when Array
|
||||
data.map {|hash| FakeResponse.new(hash)}
|
||||
else
|
||||
abort "Response data for mock connection must be a Hash or an Array. Was #{data.inspect}."
|
||||
end
|
||||
|
||||
connection = flexmock('Mock connection') do |mock|
|
||||
mock.should_receive(:request).and_return(*return_values).at_least.once
|
||||
end
|
||||
|
||||
flexmock(klass).should_receive(:connection).and_return(connection)
|
||||
end
|
||||
end
|
Загрузка…
Ссылка в новой задаче