right_aws 1.2.0 → 1.3.0
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/History.txt +16 -0
- data/Manifest.txt +2 -0
- data/Rakefile +34 -2
- data/lib/awsbase/benchmark_fix.rb +1 -1
- data/lib/awsbase/right_awsbase.rb +154 -4
- data/lib/ec2/right_ec2.rb +11 -83
- data/lib/right_aws.rb +2 -2
- data/lib/s3/right_s3_interface.rb +12 -128
- data/lib/sqs/right_sqs_interface.rb +14 -84
- data/test/http_connection.rb +85 -0
- data/test/s3/test_right_s3.rb +34 -4
- data/test/s3/test_right_s3_stubbed.rb +70 -0
- data/test/sqs/test_right_sqs.rb +17 -0
- data/test/ts_right_aws.rb +2 -0
- metadata +5 -3
data/History.txt
CHANGED
@@ -47,4 +47,20 @@ r1581 | tve | 2007-08-24 16:21:45 -0700 (Fri, 24 Aug 2007) | 1 line
|
|
47
47
|
Improved RightAws documentation
|
48
48
|
------------------------------------------------------------------------
|
49
49
|
|
50
|
+
== 1.3.0 / 2007-09-26
|
51
|
+
------------------------------------------------------------------------
|
52
|
+
r1754 | todd | 2007-09-19 13:48:34 -0700 (Wed, 19 Sep 2007) | 6 lines
|
53
|
+
|
54
|
+
(#487, #488) Consolidate a lot of code that was repeated in three places.
|
55
|
+
Fix error handling path when using streaming GET interfaces with S3.
|
56
|
+
Also add a stub for RightHttpConnection which
|
57
|
+
allows more control over the unit tests. Expand the unit tests and coverage
|
58
|
+
tests.
|
59
|
+
------------------------------------------------------------------------
|
60
|
+
r1755 | todd | 2007-09-19 14:29:19 -0700 (Wed, 19 Sep 2007) | 2 lines
|
61
|
+
|
62
|
+
(#487) RDoc fixes after code consolidation
|
63
|
+
|
64
|
+
------------------------------------------------------------------------
|
65
|
+
|
50
66
|
|
data/Manifest.txt
CHANGED
@@ -15,8 +15,10 @@ test/ec2/test_helper.rb
|
|
15
15
|
test/ec2/test_right_ec2.rb
|
16
16
|
test/s3/test_helper.rb
|
17
17
|
test/s3/test_right_s3.rb
|
18
|
+
test/s3/test_right_s3_stubbed.rb
|
18
19
|
test/sqs/test_helper.rb
|
19
20
|
test/sqs/test_right_sqs.rb
|
20
21
|
test/ts_right_aws.rb
|
21
22
|
test/test_credentials.rb
|
23
|
+
test/http_connection.rb
|
22
24
|
|
data/Rakefile
CHANGED
@@ -7,6 +7,8 @@ require 'rcov/rcovtask'
|
|
7
7
|
$: << File.dirname(__FILE__)
|
8
8
|
require 'lib/right_aws.rb'
|
9
9
|
|
10
|
+
testglobs = ["test/ts_right_aws.rb"]
|
11
|
+
|
10
12
|
Hoe.new('right_aws', RightAws::VERSION::STRING) do |p|
|
11
13
|
p.rubyforge_name = 'rightaws'
|
12
14
|
p.author = 'RightScale, Inc.'
|
@@ -17,14 +19,44 @@ Hoe.new('right_aws', RightAws::VERSION::STRING) do |p|
|
|
17
19
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
18
20
|
p.remote_rdoc_dir = "/right_aws_gem_doc"
|
19
21
|
p.extra_deps = [['right_http_connection','>= 0.1.4']]
|
20
|
-
p.test_globs =
|
22
|
+
p.test_globs = testglobs
|
21
23
|
end
|
22
24
|
|
23
25
|
desc "Analyze code coverage of the unit tests."
|
24
26
|
Rcov::RcovTask.new do |t|
|
25
|
-
t.test_files = FileList[
|
27
|
+
t.test_files = FileList[testglobs]
|
26
28
|
#t.verbose = true # uncomment to see the executed command
|
27
29
|
end
|
30
|
+
|
31
|
+
desc "Test just the SQS interface"
|
32
|
+
task :testsqs do
|
33
|
+
require 'test/test_credentials'
|
34
|
+
require 'test/http_connection'
|
35
|
+
TestCredentials.get_credentials
|
36
|
+
require 'test/sqs/test_right_sqs.rb'
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Test just the S3 interface"
|
40
|
+
task :tests3 do
|
41
|
+
require 'test/test_credentials'
|
42
|
+
require 'test/http_connection'
|
43
|
+
TestCredentials.get_credentials
|
44
|
+
require 'test/s3/test_right_s3.rb'
|
45
|
+
end
|
28
46
|
|
47
|
+
desc "Test just the S3 interface using local stubs"
|
48
|
+
task :tests3local do
|
49
|
+
require 'test/test_credentials'
|
50
|
+
require 'test/http_connection'
|
51
|
+
TestCredentials.get_credentials
|
52
|
+
require 'test/s3/test_right_s3_stubbed.rb'
|
53
|
+
end
|
54
|
+
|
55
|
+
desc "Test just the EC2 interface"
|
56
|
+
task :testec2 do
|
57
|
+
require 'test/test_credentials'
|
58
|
+
TestCredentials.get_credentials
|
59
|
+
require 'test/ec2/test_right_ec2.rb'
|
60
|
+
end
|
29
61
|
|
30
62
|
# vim: syntax=Ruby
|
@@ -24,9 +24,30 @@
|
|
24
24
|
# Test
|
25
25
|
module RightAws
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
class AwsUtils #:nodoc:
|
28
|
+
def self.sign(aws_secret_access_key, auth_string)
|
29
|
+
Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new("sha1"), aws_secret_access_key, auth_string)).strip
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
class AwsBenchmarkingBlock #:nodoc:
|
35
|
+
attr_accessor :xml, :service
|
36
|
+
def initialize
|
37
|
+
# Benchmark::Tms instance for service (Ec2, S3, or SQS) access benchmarking.
|
38
|
+
@service = Benchmark::Tms.new()
|
39
|
+
# Benchmark::Tms instance for XML parsing benchmarking.
|
40
|
+
@xml = Benchmark::Tms.new()
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class RightAwsBase
|
45
|
+
|
46
|
+
# Amazon HTTP Error handling
|
47
|
+
|
48
|
+
# Text, if found in an error message returned by AWS, indicates that this may be a transient
|
49
|
+
# error. Transient errors are automatically retried with exponential back-off.
|
50
|
+
AMAZON_PROBLEMS = [ 'internal service error',
|
30
51
|
'is currently unavailable',
|
31
52
|
'no response from',
|
32
53
|
'Please try again',
|
@@ -36,12 +57,141 @@ module RightAws
|
|
36
57
|
'This application is not currently available',
|
37
58
|
'InsufficientInstanceCapacity'
|
38
59
|
]
|
60
|
+
@@amazon_problems = AMAZON_PROBLEMS
|
61
|
+
# Returns a list of Amazon service responses which are known to be transient problems.
|
62
|
+
# We have to re-request if we get any of them, because the problem will probably disappear.
|
63
|
+
# By default this method returns the same value as the AMAZON_PROBLEMS const.
|
64
|
+
def self.amazon_problems
|
65
|
+
@@amazon_problems
|
66
|
+
end
|
67
|
+
|
68
|
+
# Sets the list of Amazon side problems. Use in conjunction with the
|
69
|
+
# getter to append problems.
|
70
|
+
def self.amazon_problems=(problems_list)
|
71
|
+
@@amazon_problems = problems_list
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
module RightAwsBaseInterface
|
77
|
+
|
78
|
+
# Current aws_access_key_id
|
79
|
+
attr_reader :aws_access_key_id
|
80
|
+
# Last HTTP request object
|
81
|
+
attr_reader :last_request
|
82
|
+
# Last HTTP response object
|
83
|
+
attr_reader :last_response
|
84
|
+
# Last AWS errors list (used by AWSErrorHandler)
|
85
|
+
attr_accessor :last_errors
|
86
|
+
# Last AWS request id (used by AWSErrorHandler)
|
87
|
+
attr_accessor :last_request_id
|
88
|
+
# Logger object
|
89
|
+
attr_accessor :logger
|
90
|
+
# Initial params hash
|
91
|
+
attr_accessor :params
|
92
|
+
|
93
|
+
def init(service_info, aws_access_key_id, aws_secret_access_key, params={}) #:nodoc:
|
94
|
+
@params = params
|
95
|
+
raise AwsError.new("AWS access keys are required to operate on #{service_info[:name]}") \
|
96
|
+
if aws_access_key_id.blank? || aws_secret_access_key.blank?
|
97
|
+
@aws_access_key_id = aws_access_key_id
|
98
|
+
@aws_secret_access_key = aws_secret_access_key
|
99
|
+
@params[:server] ||= service_info[:default_host]
|
100
|
+
@params[:port] ||= service_info[:default_port]
|
101
|
+
@params[:protocol] ||= service_info[:default_protocol]
|
102
|
+
@params[:multi_thread] ||= defined?(AWS_DAEMON)
|
103
|
+
@logger = @params[:logger]
|
104
|
+
@logger = RAILS_DEFAULT_LOGGER if !@logger && defined?(RAILS_DEFAULT_LOGGER)
|
105
|
+
@logger = Logger.new(STDOUT) if !@logger
|
106
|
+
@logger.info "New #{self.class.name} using #{@params[:multi_thread] ? 'multi' : 'single'}-threaded mode"
|
107
|
+
@error_handler = nil
|
108
|
+
end
|
109
|
+
|
110
|
+
def on_exception(options={:raise=>true, :log=>true}) # :nodoc:
|
111
|
+
AwsError::on_aws_exception(self, options)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Return +true+ if this instance works in multi_thread mode and +false+ otherwise.
|
115
|
+
def multi_thread
|
116
|
+
@params[:multi_thread]
|
117
|
+
end
|
118
|
+
|
119
|
+
def request_info_impl(connection, benchblock, request, parser, &block) #:nodoc:
|
120
|
+
@last_request = request[:request]
|
121
|
+
@last_response = nil
|
122
|
+
response=nil
|
123
|
+
blockexception = nil
|
124
|
+
|
125
|
+
if(block != nil)
|
126
|
+
# TRB 9/17/07 Careful - because we are passing in blocks, we get a situation where
|
127
|
+
# an exception may get thrown in the block body (which is high-level
|
128
|
+
# code either here or in the application) but gets caught in the
|
129
|
+
# low-level code of HttpConnection. The solution is not to let any
|
130
|
+
# exception escape the block that we pass to HttpConnection::request.
|
131
|
+
# Exceptions can originate from code directly in the block, or from user
|
132
|
+
# code called in the other block which is passed to response.read_body.
|
133
|
+
benchblock.service.add! do
|
134
|
+
responsehdr = connection.request(request) do |response|
|
135
|
+
#########
|
136
|
+
begin
|
137
|
+
@last_response = response
|
138
|
+
if response.is_a?(Net::HTTPSuccess)
|
139
|
+
@error_handler = nil
|
140
|
+
response.read_body(&block)
|
141
|
+
else
|
142
|
+
@error_handler = AWSErrorHandler.new(self, parser, self.class.amazon_problems) unless @error_handler
|
143
|
+
check_result = @error_handler.check(request)
|
144
|
+
if check_result
|
145
|
+
@error_handler = nil
|
146
|
+
return check_result
|
147
|
+
end
|
148
|
+
raise AwsError.new(@last_errors, @last_response.code, @last_request_id)
|
149
|
+
end
|
150
|
+
rescue Exception => e
|
151
|
+
blockexception = e
|
152
|
+
end
|
153
|
+
end
|
154
|
+
#########
|
155
|
+
|
156
|
+
#OK, now we are out of the block passed to the lower level
|
157
|
+
if(blockexception)
|
158
|
+
raise blockexception
|
159
|
+
end
|
160
|
+
benchblock.xml.add! do
|
161
|
+
parser.parse(responsehdr)
|
162
|
+
end
|
163
|
+
return parser.result
|
164
|
+
end
|
165
|
+
else
|
166
|
+
benchblock.service.add!{ response = connection.request(request) }
|
167
|
+
# check response for errors...
|
168
|
+
@last_response = response
|
169
|
+
if response.is_a?(Net::HTTPSuccess)
|
170
|
+
@error_handler = nil
|
171
|
+
benchblock.xml.add! { parser.parse(response) }
|
172
|
+
return parser.result
|
173
|
+
else
|
174
|
+
@error_handler = AWSErrorHandler.new(self, parser, self.class.amazon_problems) unless @error_handler
|
175
|
+
check_result = @error_handler.check(request)
|
176
|
+
if check_result
|
177
|
+
@error_handler = nil
|
178
|
+
return check_result
|
179
|
+
end
|
180
|
+
raise AwsError.new(@last_errors, @last_response.code, @last_request_id)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
rescue
|
184
|
+
@error_handler = nil
|
185
|
+
raise
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
|
39
190
|
|
40
191
|
# Exception class to signal any Amazon errors. All errors occuring during calls to Amazon's
|
41
192
|
# web services raise this type of error.
|
42
193
|
# Attribute inherited by RuntimeError:
|
43
194
|
# message - the text of the error, generally as returned by AWS in its XML response.
|
44
|
-
|
45
195
|
class AwsError < RuntimeError
|
46
196
|
|
47
197
|
# either an array of errors where each item is itself an array of [code, message]),
|
data/lib/ec2/right_ec2.rb
CHANGED
@@ -63,7 +63,8 @@ module RightAws
|
|
63
63
|
# Error handling: all operations raise an RightAws::AwsError in case
|
64
64
|
# of problems. Note that transient errors are automatically retried.
|
65
65
|
|
66
|
-
class Ec2
|
66
|
+
class Ec2 < RightAwsBase
|
67
|
+
include RightAwsBaseInterface
|
67
68
|
|
68
69
|
SIGNATURE_VERSION = "1"
|
69
70
|
# Amazon EC2 API version being used
|
@@ -75,43 +76,13 @@ module RightAws
|
|
75
76
|
# Default addressing type (public=NAT, direct=no-NAT) used when launching instances.
|
76
77
|
DEFAULT_ADDRESSING_TYPE = 'public'
|
77
78
|
DNS_ADDRESSING_SET = ['public','direct']
|
78
|
-
|
79
|
-
# A list of Amazon problems we can handle by AWSErrorHandler.
|
80
|
-
@@amazon_problems = RightAws::AMAZON_PROBLEMS
|
81
|
-
|
82
|
-
# Current aws_access_key_id
|
83
|
-
attr_reader :aws_access_key_id
|
84
|
-
# Last HTTP request object
|
85
|
-
attr_reader :last_request
|
86
|
-
# Last HTTP response object
|
87
|
-
attr_reader :last_response
|
88
|
-
# Last AWS errors list (used by AWSErrorHandler)
|
89
|
-
attr_accessor :last_errors
|
90
|
-
# Last AWS request id (used by AWSErrorHandler)
|
91
|
-
attr_accessor :last_request_id
|
92
|
-
# Logger object, used by this class to generate log messages
|
93
|
-
attr_accessor :logger
|
94
|
-
# Option params passed into new
|
95
|
-
attr_accessor :params
|
96
|
-
|
97
|
-
@@bench_ec2 = Benchmark::Tms.new()
|
98
|
-
@@bench_xml = Benchmark::Tms.new()
|
99
|
-
|
100
|
-
# Benchmark::Tms instance that accumulates time spent in requests to EC2.
|
101
|
-
def self.bench_ec2; @@bench_ec2; end
|
102
|
-
|
103
|
-
# Benchmark::Tms instance that accumulates time spent in XML parsing.
|
104
|
-
def self.bench_xml; @@bench_xml; end
|
105
79
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
@@amazon_problems
|
80
|
+
@@bench = AwsBenchmarkingBlock.new
|
81
|
+
def self.bench_xml
|
82
|
+
@@bench.xml
|
110
83
|
end
|
111
|
-
|
112
|
-
|
113
|
-
def self.amazon_problems=(problems_list)
|
114
|
-
@@amazon_problems = problems_list
|
84
|
+
def self.bench_ec2
|
85
|
+
@@bench.service
|
115
86
|
end
|
116
87
|
|
117
88
|
# Create a new handle to an EC2 account. All handles share the same per process or per thread
|
@@ -124,31 +95,10 @@ module RightAws
|
|
124
95
|
# * <tt>:logger</tt>: for log messages, default: RAILS_DEFAULT_LOGGER else STDOUT
|
125
96
|
#
|
126
97
|
def initialize(aws_access_key_id, aws_secret_access_key, params={})
|
127
|
-
|
128
|
-
|
129
|
-
if aws_access_key_id.blank? || aws_secret_access_key.blank?
|
130
|
-
@aws_access_key_id = aws_access_key_id
|
131
|
-
@aws_secret_access_key = aws_secret_access_key
|
132
|
-
# params
|
133
|
-
@params[:server] ||= DEFAULT_HOST
|
134
|
-
@params[:port] ||= DEFAULT_PORT
|
135
|
-
@params[:protocol] ||= DEFAULT_PROTOCOL
|
136
|
-
@params[:multi_thread] ||= defined?(AWS_DAEMON)
|
137
|
-
# set logger
|
138
|
-
@logger = @params[:logger]
|
139
|
-
@logger = RAILS_DEFAULT_LOGGER if !@logger && defined?(RAILS_DEFAULT_LOGGER)
|
140
|
-
@logger = Logger.new(STDOUT) if !@logger
|
141
|
-
@logger.info "New #{self.class.name} using #{@params[:multi_thread] ? 'multi' : 'single'}-threaded mode"
|
98
|
+
init({:name=>'EC2', :default_host => DEFAULT_HOST, :default_port => DEFAULT_PORT, :default_protocol => DEFAULT_PROTOCOL},
|
99
|
+
aws_access_key_id, aws_secret_access_key, params)
|
142
100
|
end
|
143
101
|
|
144
|
-
def on_exception(options={:raise=>true, :log=>true}) # :nodoc:
|
145
|
-
AwsError::on_aws_exception(self, options)
|
146
|
-
end
|
147
|
-
|
148
|
-
# Return +true+ if this RightEc2NativeQuery instance works in multi_thread mode and +false+ otherwise.
|
149
|
-
def multi_thread
|
150
|
-
@params[:multi_thread]
|
151
|
-
end
|
152
102
|
|
153
103
|
def generate_request(action, param={}) #:nodoc:
|
154
104
|
timestamp = ( Time::now ).utc.strftime("%Y-%m-%dT%H:%M:%S.000Z")
|
@@ -159,7 +109,7 @@ module RightAws
|
|
159
109
|
"SignatureVersion" => SIGNATURE_VERSION }
|
160
110
|
request_hash.update(param)
|
161
111
|
request_data = request_hash.sort{|a,b| (a[0].to_s.downcase)<=>(b[0].to_s.downcase)}.to_s
|
162
|
-
request_hash.update('Signature' =>
|
112
|
+
request_hash.update('Signature' => AwsUtils::sign(@aws_secret_access_key, request_data))
|
163
113
|
request_params = request_hash.to_a.collect{|key,val| key + "=" + CGI::escape(val) }.join("&")
|
164
114
|
request = Net::HTTP::Get.new("/?#{request_params}")
|
165
115
|
# prepare output hash
|
@@ -174,29 +124,7 @@ module RightAws
|
|
174
124
|
def request_info(request, parser) #:nodoc:
|
175
125
|
thread = @params[:multi_thread] ? Thread.current : Thread.main
|
176
126
|
thread[:ec2_connection] ||= Rightscale::HttpConnection.new(:exception => AwsError)
|
177
|
-
|
178
|
-
@last_response = nil
|
179
|
-
response=nil
|
180
|
-
|
181
|
-
@@bench_ec2.add!{ response = thread[:ec2_connection].request(request) }
|
182
|
-
# check response for errors...
|
183
|
-
@last_response = response
|
184
|
-
if response.is_a?(Net::HTTPSuccess)
|
185
|
-
@error_handler = nil
|
186
|
-
@@bench_xml.add! { parser.parse(response) }
|
187
|
-
return parser.result
|
188
|
-
else
|
189
|
-
@error_handler = AWSErrorHandler.new(self, parser, @@amazon_problems) unless @error_handler
|
190
|
-
check_result = @error_handler.check(request)
|
191
|
-
if check_result
|
192
|
-
@error_handler = nil
|
193
|
-
return check_result
|
194
|
-
end
|
195
|
-
raise AwsError.new(@last_errors, @last_response.code, @last_request_id)
|
196
|
-
end
|
197
|
-
rescue
|
198
|
-
@error_handler = nil
|
199
|
-
raise
|
127
|
+
request_info_impl(thread[:ec2_connection], @@bench, request, parser)
|
200
128
|
end
|
201
129
|
|
202
130
|
|
data/lib/right_aws.rb
CHANGED
@@ -48,7 +48,7 @@ require 'sqs/right_sqs'
|
|
48
48
|
module RightAws #:nodoc:
|
49
49
|
module VERSION #:nodoc:
|
50
50
|
MAJOR = 1
|
51
|
-
MINOR =
|
51
|
+
MINOR = 3
|
52
52
|
TINY = 0
|
53
53
|
|
54
54
|
STRING = [MAJOR, MINOR, TINY].join('.')
|
@@ -59,7 +59,7 @@ end
|
|
59
59
|
|
60
60
|
# We also want everything available in the Rightscale namespace for backward
|
61
61
|
# compatibility reasons.
|
62
|
-
module Rightscale
|
62
|
+
module Rightscale #:nodoc:
|
63
63
|
include RightAws
|
64
64
|
extend RightAws
|
65
65
|
end
|
@@ -23,7 +23,8 @@
|
|
23
23
|
|
24
24
|
module RightAws
|
25
25
|
|
26
|
-
class S3Interface
|
26
|
+
class S3Interface < RightAwsBase
|
27
|
+
include RightAwsBaseInterface
|
27
28
|
|
28
29
|
DEFAULT_HOST = 's3.amazonaws.com'
|
29
30
|
DEFAULT_PORT = 443
|
@@ -33,54 +34,15 @@ module RightAws
|
|
33
34
|
AMAZON_HEADER_PREFIX = 'x-amz-'
|
34
35
|
AMAZON_METADATA_PREFIX = 'x-amz-meta-'
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
# TODO TRB 6/19/07 - all the below accessors are shared in the
|
40
|
-
# three service gems. See if is it reasonable to stick these
|
41
|
-
# in an interface class in right_awsbase that we can mixin
|
42
|
-
#
|
43
|
-
# Same for the benchmarking code - all three service gems have
|
44
|
-
# the same. Break out into a helper class. Also look at the
|
45
|
-
# benchmarking fix as a good thing to move to common code.
|
46
|
-
|
47
|
-
# Current aws_access_key_id
|
48
|
-
attr_reader :aws_access_key_id
|
49
|
-
# Last HTTP request object
|
50
|
-
attr_reader :last_request
|
51
|
-
# Last HTTP response object
|
52
|
-
attr_reader :last_response
|
53
|
-
# Last AWS errors list (used by AWSErrorHandler)
|
54
|
-
attr_accessor :last_errors
|
55
|
-
# Last AWS request id (used by AWSErrorHandler)
|
56
|
-
attr_accessor :last_request_id
|
57
|
-
# Logger object
|
58
|
-
attr_accessor :logger
|
59
|
-
# Initial params hash
|
60
|
-
attr_accessor :params
|
61
|
-
|
62
|
-
@@bench_s3 = Benchmark::Tms.new()
|
63
|
-
@@bench_xml = Benchmark::Tms.new()
|
64
|
-
|
65
|
-
# Benchmark::Tms instance for S3 access benchmark.
|
66
|
-
def self.bench_s3; @@bench_s3; end
|
67
|
-
|
68
|
-
# Benchmark::Tms instance for XML parsing benchmark.
|
69
|
-
def self.bench_xml; @@bench_xml; end # For benchmark puposes.
|
70
|
-
|
71
|
-
# Returns a list of Amazon service responses which are known to be transient problems.
|
72
|
-
# We have to re-request if we get any of them, because the problem will probably disappear.
|
73
|
-
# By default this method returns the same value as the AMAZON_PROBLEMS const.
|
74
|
-
def self.amazon_problems
|
75
|
-
@@amazon_problems
|
37
|
+
@@bench = AwsBenchmarkingBlock.new
|
38
|
+
def self.bench_xml
|
39
|
+
@@bench.xml
|
76
40
|
end
|
77
|
-
|
78
|
-
|
79
|
-
# getter to append problems.
|
80
|
-
def self.amazon_problems=(problems_list)
|
81
|
-
@@amazon_problems = problems_list
|
41
|
+
def self.bench_s3
|
42
|
+
@@bench.service
|
82
43
|
end
|
83
44
|
|
45
|
+
|
84
46
|
# Creates new RightS3 instance.
|
85
47
|
#
|
86
48
|
# s3 = RightAws::S3Interface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX', {:multi_thread => true, :logger => Logger.new('/tmp/x.log')}) #=> #<RightS3:0xb7b3c27c>
|
@@ -94,39 +56,10 @@ module RightAws
|
|
94
56
|
# :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
|
95
57
|
#
|
96
58
|
def initialize(aws_access_key_id, aws_secret_access_key, params={})
|
97
|
-
|
98
|
-
|
99
|
-
if aws_access_key_id.blank? || aws_secret_access_key.blank?
|
100
|
-
|
101
|
-
# TODO TRB 6/19/07 - keys, basic params, and logger are all
|
102
|
-
# candidates to break out into a helper class common to all
|
103
|
-
# service gems. Stick the helper in right_awsbase
|
104
|
-
@aws_access_key_id = aws_access_key_id
|
105
|
-
@aws_secret_access_key = aws_secret_access_key
|
106
|
-
# params
|
107
|
-
@params[:server] ||= DEFAULT_HOST
|
108
|
-
@params[:port] ||= DEFAULT_PORT
|
109
|
-
@params[:protocol] ||= DEFAULT_PROTOCOL
|
110
|
-
@params[:multi_thread] ||= defined?(AWS_DAEMON)
|
111
|
-
# set logger
|
112
|
-
@logger = @params[:logger]
|
113
|
-
@logger = RAILS_DEFAULT_LOGGER if !@logger && defined?(RAILS_DEFAULT_LOGGER)
|
114
|
-
@logger = Logger.new(STDOUT) if !@logger
|
115
|
-
@logger.info "New #{self.class.name} using #{@params[:multi_thread] ? 'multi' : 'single'}-threaded mode"
|
116
|
-
@error_handler = nil
|
117
|
-
end
|
118
|
-
|
119
|
-
# TODO TRB 6/19/07 - Service gem common method
|
120
|
-
def on_exception(options={:raise=>true, :log=>true}) # :nodoc:
|
121
|
-
RightAws::AwsError::on_aws_exception(self, options)
|
59
|
+
init({:name=>'S3', :default_host => DEFAULT_HOST, :default_port => DEFAULT_PORT, :default_protocol => DEFAULT_PROTOCOL},
|
60
|
+
aws_access_key_id, aws_secret_access_key, params)
|
122
61
|
end
|
123
62
|
|
124
|
-
# TODO TRB 6/19/07 - Service gem common method
|
125
|
-
|
126
|
-
# Return the +true+ if this RightS3 instance works in multi_thread state and +false+ otherwise.
|
127
|
-
def multi_thread
|
128
|
-
@params[:multi_thread]
|
129
|
-
end
|
130
63
|
|
131
64
|
#-----------------------------------------------------------------
|
132
65
|
# Requests
|
@@ -172,7 +105,7 @@ module RightAws
|
|
172
105
|
headers.each { |key, value| request[key.to_s] = value }
|
173
106
|
#generate auth strings
|
174
107
|
auth_string = canonical_string(request.method, request.path, request.to_hash)
|
175
|
-
signature =
|
108
|
+
signature = AwsUtils::sign(@aws_secret_access_key, auth_string)
|
176
109
|
# set other headers
|
177
110
|
request['Authorization'] = "AWS #{@aws_access_key_id}:#{signature}"
|
178
111
|
# prepare output hash
|
@@ -184,59 +117,10 @@ module RightAws
|
|
184
117
|
|
185
118
|
# Sends request to Amazon and parses the response.
|
186
119
|
# Raises AwsError if any banana happened.
|
187
|
-
# TODO TRB 6/19/07:
|
188
|
-
# request_info is a candidate to move to right_awsbase
|
189
|
-
# because it currently appears (in identical form) in right_s3,
|
190
|
-
# right_ec2, and right_sqs
|
191
120
|
def request_info(request, parser, &block) # :nodoc:
|
192
121
|
thread = @params[:multi_thread] ? Thread.current : Thread.main
|
193
122
|
thread[:s3_connection] ||= Rightscale::HttpConnection.new(:exception => RightAws::AwsError)
|
194
|
-
|
195
|
-
@last_response = nil
|
196
|
-
response=nil
|
197
|
-
|
198
|
-
if(block != nil)
|
199
|
-
@@bench_s3.add! do
|
200
|
-
responsehdr = thread[:s3_connection].request(request) do |response|
|
201
|
-
if response.is_a?(Net::HTTPSuccess)
|
202
|
-
@error_handler = nil
|
203
|
-
response.read_body(&block)
|
204
|
-
else
|
205
|
-
@error_handler = AWSErrorHandler.new(self, parser, @@amazon_problems) unless @error_handler
|
206
|
-
check_result = @error_handler.check(request)
|
207
|
-
if check_result
|
208
|
-
@error_handler = nil
|
209
|
-
return check_result
|
210
|
-
end
|
211
|
-
raise AwsError.new(@last_errors, @last_response.code, @last_request_id)
|
212
|
-
end
|
213
|
-
end
|
214
|
-
@@bench_xml.add! do
|
215
|
-
parser.parse(responsehdr)
|
216
|
-
end
|
217
|
-
return parser.result
|
218
|
-
end
|
219
|
-
else
|
220
|
-
@@bench_s3.add!{ response = thread[:s3_connection].request(request) }
|
221
|
-
# check response for errors...
|
222
|
-
@last_response = response
|
223
|
-
if response.is_a?(Net::HTTPSuccess)
|
224
|
-
@error_handler = nil
|
225
|
-
@@bench_xml.add! { parser.parse(response) }
|
226
|
-
return parser.result
|
227
|
-
else
|
228
|
-
@error_handler = AWSErrorHandler.new(self, parser, @@amazon_problems) unless @error_handler
|
229
|
-
check_result = @error_handler.check(request)
|
230
|
-
if check_result
|
231
|
-
@error_handler = nil
|
232
|
-
return check_result
|
233
|
-
end
|
234
|
-
raise AwsError.new(@last_errors, @last_response.code, @last_request_id)
|
235
|
-
end
|
236
|
-
end
|
237
|
-
rescue
|
238
|
-
@error_handler = nil
|
239
|
-
raise
|
123
|
+
request_info_impl(thread[:s3_connection], @@bench, request, parser, &block)
|
240
124
|
end
|
241
125
|
|
242
126
|
|
@@ -23,7 +23,8 @@
|
|
23
23
|
|
24
24
|
module RightAws
|
25
25
|
|
26
|
-
class SqsInterface
|
26
|
+
class SqsInterface < RightAwsBase
|
27
|
+
include RightAwsBaseInterface
|
27
28
|
|
28
29
|
SIGNATURE_VERSION = "1"
|
29
30
|
API_VERSION = "2007-05-01"
|
@@ -32,45 +33,17 @@ module RightAws
|
|
32
33
|
DEFAULT_PROTOCOL = 'https'
|
33
34
|
REQUEST_TTL = 30
|
34
35
|
DEFAULT_VISIBILITY_TIMEOUT = 30
|
35
|
-
# A list of Amazon problems we can handle via AWSErrorHandler.
|
36
|
-
@@amazon_problems = RightAws::AMAZON_PROBLEMS
|
37
|
-
|
38
|
-
# Current aws_access_key_id
|
39
|
-
attr_reader :aws_access_key_id
|
40
|
-
# Last HTTP request object
|
41
|
-
attr_reader :last_request
|
42
|
-
# Last HTTP response object
|
43
|
-
attr_reader :last_response
|
44
|
-
# Last AWS errors list (used by AWSErrorHandler)
|
45
|
-
attr_accessor :last_errors
|
46
|
-
# Last AWS request id (used by AWSErrorHandler)
|
47
|
-
attr_accessor :last_request_id
|
48
|
-
# Logger object
|
49
|
-
attr_accessor :logger
|
50
|
-
# Initial params hash
|
51
|
-
attr_accessor :params
|
52
|
-
|
53
|
-
@@bench_sqs = Benchmark::Tms.new()
|
54
|
-
@@bench_xml = Benchmark::Tms.new()
|
55
|
-
|
56
|
-
# Benchmark::Tms instance for SQS access benchmarking.
|
57
|
-
def self.bench_sqs; @@bench_sqs; end
|
58
|
-
# Benchmark::Tms instance for XML parsing benchmarking.
|
59
|
-
def self.bench_xml; @@bench_xml; end # For benchmark purposes.
|
60
36
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
@@amazon_problems
|
37
|
+
|
38
|
+
@@bench = AwsBenchmarkingBlock.new
|
39
|
+
def self.bench_xml
|
40
|
+
@@bench.xml
|
66
41
|
end
|
67
|
-
|
68
|
-
|
69
|
-
# getter to append problems.
|
70
|
-
def self.amazon_problems=(problems_list)
|
71
|
-
@@amazon_problems = problems_list
|
42
|
+
def self.bench_sqs
|
43
|
+
@@bench.service
|
72
44
|
end
|
73
45
|
|
46
|
+
|
74
47
|
# Creates a new SqsInterface instance.
|
75
48
|
#
|
76
49
|
# sqs = RightAws::SqsInterface.new('1E3GDYEOGFJPIT75KDT40','hgTHt68JY07JKUY08ftHYtERkjgtfERn57DFE379', {:multi_thread => true, :logger => Logger.new('/tmp/x.log')}) #=> <RightSqs:0xb7af6264>
|
@@ -83,31 +56,10 @@ module RightAws
|
|
83
56
|
# :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
|
84
57
|
#
|
85
58
|
def initialize(aws_access_key_id, aws_secret_access_key, params={})
|
86
|
-
|
87
|
-
|
88
|
-
if aws_access_key_id.blank? || aws_secret_access_key.blank?
|
89
|
-
@aws_access_key_id = aws_access_key_id
|
90
|
-
@aws_secret_access_key = aws_secret_access_key
|
91
|
-
# params
|
92
|
-
@params[:server] ||= DEFAULT_HOST
|
93
|
-
@params[:port] ||= DEFAULT_PORT
|
94
|
-
@params[:protocol] ||= DEFAULT_PROTOCOL
|
95
|
-
@params[:multi_thread] ||= defined?(AWS_DAEMON)
|
96
|
-
# set logger
|
97
|
-
@logger = @params[:logger]
|
98
|
-
@logger = RAILS_DEFAULT_LOGGER if !@logger && defined?(RAILS_DEFAULT_LOGGER)
|
99
|
-
@logger = Logger.new(STDOUT) if !@logger
|
100
|
-
@logger.info "New #{self.class.name} using #{@params[:multi_thread] ? 'multi' : 'single'}-threaded mode"
|
101
|
-
end
|
102
|
-
|
103
|
-
def on_exception(options={:raise=>true, :log=>true}) # :nodoc:
|
104
|
-
AwsError::on_aws_exception(self, options)
|
59
|
+
init({:name=>'SQS', :default_host => DEFAULT_HOST, :default_port => DEFAULT_PORT, :default_protocol => DEFAULT_PROTOCOL},
|
60
|
+
aws_access_key_id, aws_secret_access_key, params)
|
105
61
|
end
|
106
62
|
|
107
|
-
# Return +true+ if this RightS3 instance is running in multi_thread state and +false+ otherwise.
|
108
|
-
def multi_thread
|
109
|
-
@params[:multi_thread]
|
110
|
-
end
|
111
63
|
|
112
64
|
#-----------------------------------------------------------------
|
113
65
|
# Requests
|
@@ -129,7 +81,7 @@ module RightAws
|
|
129
81
|
"SignatureVersion" => SIGNATURE_VERSION }
|
130
82
|
request_hash.update(param)
|
131
83
|
request_data = request_hash.sort{|a,b| (a[0].to_s.downcase)<=>(b[0].to_s.downcase)}.to_s
|
132
|
-
request_hash['Signature'] =
|
84
|
+
request_hash['Signature'] = AwsUtils::sign(@aws_secret_access_key, request_data)
|
133
85
|
request_params = request_hash.to_a.collect{|key,val| key.to_s + "=" + CGI::escape(val.to_s) }.join("&")
|
134
86
|
request = Net::HTTP::Get.new("#{queue_uri}?#{request_params}")
|
135
87
|
# prepare output hash
|
@@ -156,7 +108,7 @@ module RightAws
|
|
156
108
|
request['Date'] = Time.now.httpdate
|
157
109
|
# generate authorization string
|
158
110
|
auth_string = "#{method.upcase}\n#{request['content-md5']}\n#{request['Content-Type']}\n#{request['Date']}\n#{CGI::unescape(queue_uri)}"
|
159
|
-
signature =
|
111
|
+
signature = AwsUtils::sign(@aws_secret_access_key, auth_string)
|
160
112
|
# set other headers
|
161
113
|
request['Authorization'] = "AWS #{@aws_access_key_id}:#{signature}"
|
162
114
|
request['AWS-Version'] = API_VERSION
|
@@ -173,29 +125,7 @@ module RightAws
|
|
173
125
|
def request_info(request, parser) # :nodoc:
|
174
126
|
thread = @params[:multi_thread] ? Thread.current : Thread.main
|
175
127
|
thread[:sqs_connection] ||= Rightscale::HttpConnection.new(:exception => AwsError)
|
176
|
-
|
177
|
-
@last_response = nil
|
178
|
-
response=nil
|
179
|
-
|
180
|
-
@@bench_sqs.add!{ response = thread[:sqs_connection].request(request) }
|
181
|
-
# check response for errors...
|
182
|
-
@last_response = response
|
183
|
-
if response.is_a?(Net::HTTPSuccess)
|
184
|
-
@error_handler = nil
|
185
|
-
@@bench_xml.add! { parser.parse(response) }
|
186
|
-
return parser.result
|
187
|
-
else
|
188
|
-
@error_handler = AWSErrorHandler.new(self, parser, @@amazon_problems) unless @error_handler
|
189
|
-
check_result = @error_handler.check(request)
|
190
|
-
if check_result
|
191
|
-
@error_handler = nil
|
192
|
-
return check_result
|
193
|
-
end
|
194
|
-
raise AwsError.new(@last_errors, @last_response.code, @last_request_id)
|
195
|
-
end
|
196
|
-
rescue
|
197
|
-
@error_handler = nil
|
198
|
-
raise
|
128
|
+
request_info_impl(thread[:sqs_connection], @@bench, request, parser)
|
199
129
|
end
|
200
130
|
|
201
131
|
|
@@ -0,0 +1,85 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2007 RightScale, Inc.
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
'Software'), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
19
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
20
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
=end
|
23
|
+
|
24
|
+
# Stub extension/redefinition of RightHttpConnection for testing purposes.
|
25
|
+
require 'net/http'
|
26
|
+
require 'right_http_connection'
|
27
|
+
|
28
|
+
module Net
|
29
|
+
class HTTPResponse
|
30
|
+
alias_method :real_body, :body
|
31
|
+
def setmsg(msg)
|
32
|
+
@mymsg = msg
|
33
|
+
end
|
34
|
+
|
35
|
+
def body
|
36
|
+
@mymsg ? @mymsg : real_body
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module Rightscale
|
42
|
+
|
43
|
+
class HttpConnection
|
44
|
+
@@response_stack = []
|
45
|
+
|
46
|
+
alias_method :real_request, :request
|
47
|
+
|
48
|
+
def request(request_params, &block)
|
49
|
+
if(@@response_stack.length == 0)
|
50
|
+
return real_request(request_params, &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
if(block)
|
54
|
+
# Do something special
|
55
|
+
else
|
56
|
+
next_response = HttpConnection::pop()
|
57
|
+
classname = Net::HTTPResponse::CODE_TO_OBJ["#{next_response[:code]}"]
|
58
|
+
response = classname.new("1.1", next_response[:code], next_response[:msg])
|
59
|
+
if(next_response[:msg])
|
60
|
+
response.setmsg(next_response[:msg])
|
61
|
+
end
|
62
|
+
response
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.reset
|
67
|
+
@@response_stack = []
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.push(code, msg=nil)
|
71
|
+
response = {:code => code, :msg => msg}
|
72
|
+
@@response_stack << response
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.pop
|
76
|
+
@@response_stack.pop
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.length
|
80
|
+
@@response_stack.length
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
data/test/s3/test_right_s3.rb
CHANGED
@@ -25,7 +25,7 @@ class TestS3 < Test::Unit::TestCase
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def test_03_list_empty_bucket
|
28
|
-
assert_equal 0, @s3.list_bucket(@bucket).size, "#{@bucket}
|
28
|
+
assert_equal 0, @s3.list_bucket(@bucket).size, "#{@bucket} isn't empty, arrgh!"
|
29
29
|
end
|
30
30
|
|
31
31
|
def test_04_put
|
@@ -44,12 +44,31 @@ class TestS3 < Test::Unit::TestCase
|
|
44
44
|
def test_06_head
|
45
45
|
assert_equal 'Woohoo1!', @s3.head(@bucket,@key1)['x-amz-meta-family'], "x-amz-meta-family header must be equal to 'Woohoo1!'"
|
46
46
|
end
|
47
|
+
|
48
|
+
|
49
|
+
def test_07_streaming_get
|
50
|
+
resp = String.new
|
51
|
+
assert_raise(Rightscale::AwsError) do
|
52
|
+
@s3.get(@bucket, 'undefined/key') do |chunk|
|
53
|
+
resp += chunk
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
resp = String.new
|
58
|
+
data1 = @s3.get(@bucket, @key1) do |chunk|
|
59
|
+
resp += chunk
|
60
|
+
end
|
61
|
+
assert_equal RIGHT_OBJECT_TEXT, resp, "Object text must be equal to '#{RIGHT_OBJECT_TEXT}'"
|
62
|
+
assert_equal @s3.get_object(@bucket, @key1), resp, "Streaming iface must return same as non-streaming"
|
63
|
+
assert_equal 'Woohoo1!', data1[:headers]['x-amz-meta-family'], "x-amz-meta-family header must be equal to 'Woohoo1!'"
|
64
|
+
end
|
47
65
|
|
48
|
-
def
|
66
|
+
def test_08_delete_folder
|
49
67
|
assert_equal 1, @s3.delete_folder(@bucket, 'test').size, "Only one key(#{@key1}) must be deleted!"
|
50
68
|
end
|
51
69
|
|
52
|
-
|
70
|
+
|
71
|
+
def test_09_delete_bucket
|
53
72
|
assert_raise(Rightscale::AwsError) { @s3.delete_bucket(@bucket) }
|
54
73
|
assert @s3.clear_bucket(@bucket), 'Clear_bucket fail'
|
55
74
|
assert_equal 0, @s3.list_bucket(@bucket).size, 'Bucket must be empty'
|
@@ -57,6 +76,7 @@ class TestS3 < Test::Unit::TestCase
|
|
57
76
|
assert !@s3.list_all_my_buckets.map{|bucket| bucket[:name]}.include?(@bucket), "#{@bucket} must not exist"
|
58
77
|
end
|
59
78
|
|
79
|
+
|
60
80
|
#---------------------------
|
61
81
|
# Rightscale::S3 classes
|
62
82
|
#---------------------------
|
@@ -212,6 +232,16 @@ class TestS3 < Test::Unit::TestCase
|
|
212
232
|
assert key1.delete
|
213
233
|
assert !key1.exists?
|
214
234
|
end
|
215
|
-
|
235
|
+
|
236
|
+
def test_36_set_amazon_problems
|
237
|
+
original_problems = RightAws::S3Interface.amazon_problems
|
238
|
+
assert(original_problems.length > 0)
|
239
|
+
RightAws::S3Interface.amazon_problems= original_problems << "A New Problem"
|
240
|
+
new_problems = RightAws::S3Interface.amazon_problems
|
241
|
+
assert_equal(new_problems, original_problems)
|
242
|
+
|
243
|
+
RightAws::S3Interface.amazon_problems= nil
|
244
|
+
assert_nil(RightAws::S3Interface.amazon_problems)
|
245
|
+
end
|
216
246
|
|
217
247
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestS3Stubbed < Test::Unit::TestCase
|
4
|
+
|
5
|
+
RIGHT_OBJECT_TEXT = 'Right test message'
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@s3 = Rightscale::S3Interface.new(TestCredentials.aws_access_key_id, TestCredentials.aws_secret_access_key)
|
9
|
+
@bucket = 'right_s3_awesome_test_bucket'
|
10
|
+
@key1 = 'test/woohoo1'
|
11
|
+
@key2 = 'test1/key/woohoo2'
|
12
|
+
@s = Rightscale::S3.new(TestCredentials.aws_access_key_id, TestCredentials.aws_secret_access_key)
|
13
|
+
Rightscale::HttpConnection.reset
|
14
|
+
end
|
15
|
+
|
16
|
+
# Non-remote tests: these use the stub version of Rightscale::HTTPConnection
|
17
|
+
def test_101_create_bucket
|
18
|
+
Rightscale::HttpConnection.push(409, 'The named bucket you tried to create already exists')
|
19
|
+
Rightscale::HttpConnection.push(500, 'We encountered an internal error. Please try again.')
|
20
|
+
Rightscale::HttpConnection.push(500, 'We encountered an internal error. Please try again.')
|
21
|
+
assert_raise RightAws::AwsError do
|
22
|
+
@s3.create_bucket(@bucket)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_102_list_all_my_buckets_failure
|
27
|
+
Rightscale::HttpConnection.push(401, 'Unauthorized')
|
28
|
+
assert_raise RightAws::AwsError do
|
29
|
+
@s3.list_all_my_buckets
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_103_list_empty_bucket
|
34
|
+
Rightscale::HttpConnection.push(403, 'Access Denied')
|
35
|
+
assert_raise RightAws::AwsError do
|
36
|
+
@s3.list_bucket(@bucket)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_104_put
|
41
|
+
Rightscale::HttpConnection.push(400, 'Your proposed upload exceeds the maximum allowed object size.')
|
42
|
+
Rightscale::HttpConnection.push(400, 'The Content-MD5 you specified was an invalid.')
|
43
|
+
Rightscale::HttpConnection.push(409, 'Please try again')
|
44
|
+
assert_raise RightAws::AwsError do
|
45
|
+
assert @s3.put(@bucket, @key1, RIGHT_OBJECT_TEXT, 'x-amz-meta-family'=>'Woohoo1!'), 'Put bucket fail'
|
46
|
+
end
|
47
|
+
assert_raise RightAws::AwsError do
|
48
|
+
assert @s3.put(@bucket, @key2, RIGHT_OBJECT_TEXT, 'x-amz-meta-family'=>'Woohoo2!'), 'Put bucket fail'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_105_get_and_get_object
|
53
|
+
Rightscale::HttpConnection.push(404, 'not found')
|
54
|
+
assert_raise(Rightscale::AwsError) { @s3.get(@bucket, 'undefined/key') }
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_106_head
|
58
|
+
Rightscale::HttpConnection.push(404, 'Good Luck!')
|
59
|
+
assert_raise RightAws::AwsError do
|
60
|
+
@s3.head(@bucket,@key1)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def test_109_delete_bucket
|
66
|
+
Rightscale::HttpConnection.push(403, 'Good Luck!')
|
67
|
+
assert_raise(Rightscale::AwsError) { @s3.delete_bucket(@bucket) }
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
data/test/sqs/test_right_sqs.rb
CHANGED
@@ -218,4 +218,21 @@ class TestSqs < Test::Unit::TestCase
|
|
218
218
|
assert queue.delete(true)
|
219
219
|
end
|
220
220
|
|
221
|
+
def test_27_set_amazon_problems
|
222
|
+
original_problems = RightAws::SqsInterface.amazon_problems
|
223
|
+
assert(original_problems.length > 0)
|
224
|
+
RightAws::SqsInterface.amazon_problems= original_problems << "A New Problem"
|
225
|
+
new_problems = RightAws::SqsInterface.amazon_problems
|
226
|
+
assert_equal(new_problems, original_problems)
|
227
|
+
|
228
|
+
RightAws::SqsInterface.amazon_problems= nil
|
229
|
+
assert_nil(RightAws::SqsInterface.amazon_problems)
|
230
|
+
end
|
231
|
+
|
232
|
+
def test_28_check_threading_model
|
233
|
+
assert(!@sqs.multi_thread)
|
234
|
+
newsqs = Rightscale::SqsInterface.new(TestCredentials.aws_access_key_id, TestCredentials.aws_secret_access_key, {:multi_thread => true})
|
235
|
+
assert(newsqs.multi_thread)
|
236
|
+
end
|
237
|
+
|
221
238
|
end
|
data/test/ts_right_aws.rb
CHANGED
@@ -3,8 +3,10 @@ $: << File.dirname(__FILE__)
|
|
3
3
|
require 'test_credentials'
|
4
4
|
TestCredentials.get_credentials
|
5
5
|
|
6
|
+
require 'http_connection'
|
6
7
|
require 'awsbase/test_right_awsbase.rb'
|
7
8
|
require 'ec2/test_right_ec2.rb'
|
8
9
|
require 's3/test_right_s3.rb'
|
10
|
+
require 's3/test_right_s3_stubbed.rb'
|
9
11
|
require 'sqs/test_right_sqs.rb'
|
10
12
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: right_aws
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.
|
7
|
-
date: 2007-09-
|
6
|
+
version: 1.3.0
|
7
|
+
date: 2007-09-26 00:00:00 -07:00
|
8
8
|
summary: Interface classes for the Amazon EC2, SQS, and S3 Web Services
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -46,10 +46,12 @@ files:
|
|
46
46
|
- test/ec2/test_right_ec2.rb
|
47
47
|
- test/s3/test_helper.rb
|
48
48
|
- test/s3/test_right_s3.rb
|
49
|
+
- test/s3/test_right_s3_stubbed.rb
|
49
50
|
- test/sqs/test_helper.rb
|
50
51
|
- test/sqs/test_right_sqs.rb
|
51
52
|
- test/ts_right_aws.rb
|
52
53
|
- test/test_credentials.rb
|
54
|
+
- test/http_connection.rb
|
53
55
|
test_files:
|
54
56
|
- test/ts_right_aws.rb
|
55
57
|
rdoc_options:
|
@@ -82,5 +84,5 @@ dependencies:
|
|
82
84
|
requirements:
|
83
85
|
- - ">="
|
84
86
|
- !ruby/object:Gem::Version
|
85
|
-
version: 1.
|
87
|
+
version: 1.3.0
|
86
88
|
version:
|