forked from aws/aws-sdk-ruby
/
client_spec.rb
215 lines (173 loc) · 7.37 KB
/
client_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
require_relative '../spec_helper'
module Aws
describe 'Client' do
describe 'response stubbing' do
before(:each) do
stub_const('ENV', {})
end
ResponseStubbingExample = ApiHelper.sample_service
let(:options) {{
stub_responses: true,
region: 'us-east-1',
access_key_id: 'akid',
secret_access_key: 'secret',
}}
let(:client_class) { ResponseStubbingExample.const_get(:Client) }
let(:client) { client_class.new(options) }
it 'requires a region' do
expect {
client_class.new(access_key_id:'akid', secret_access_key: 'secret')
}.to raise_error(Aws::Errors::MissingRegionError)
end
context 'when requests are signed' do
let(:client_class) do
ApiHelper
.sample_service(metadata: {'signatureVersion' => 'v4'})
.const_get(:Client)
end
it 'raises an error when credentials are nil' do
creds = Credentials.new(nil, nil)
client = client_class.new(credentials: creds, region: 'us-east-1', stub_responses: true)
expect do
client.example_operation
end.to raise_error(Aws::Errors::MissingCredentialsError)
end
it 'raises an error when credentials are empty' do
creds = Credentials.new('', '')
client = client_class.new(credentials: creds, region: 'us-east-1', stub_responses: true)
expect do
client.example_operation
end.to raise_error(Aws::Errors::MissingCredentialsError)
end
end
it 'raises a helpful error on possible incorrect regions' do
# simulate an error from connecting to an unknown endpoint
stub_request(:any, /.*/).
to_raise(SocketError.new("Failed to open TCP connection to s3.us-west-2a.amazonaws.com:443 (getaddrinfo: nodename nor servname provided, or not known"))
client = client_class.new(
region: 'us-west-2a',
credentials: Credentials.new('akid', 'secret')
)
error = nil
begin
client.example_operation
rescue => e
error = e
end
expect(e).to be_kind_of(Errors::NoSuchEndpointError)
expect(e.context.retries).to be(3) # updated to retry based on customer request
expect(e.message).to include('us-east-1')
expect(e.message).to include('us-west-1')
expect(e.message).to include('cn-north-1')
expect(e.message).to include(<<-MSG)
Encountered a `SocketError` while attempting to connect to:
https://svc.us-west-2a.amazonaws.com
This is typically the result of an invalid `:region` option or a
poorly formatted `:endpoint` option.
* Avoid configuring the `:endpoint` option directly. Endpoints are constructed
from the `:region`. The `:endpoint` option is reserved for certain services
or for connecting to non-standard test endpoints.
* Not every service is available in every region.
* Never suffix region names with availability zones.
Use "us-east-1", not "us-east-1a"
Known AWS regions include (not specific to this service):
MSG
end
it 'skips the credential provider chain' do
expect(Aws::CredentialProviderChain).not_to receive(:new)
creds = client_class.new(stub_responses:true).config.credentials
expect(creds).to be_kind_of(Credentials)
expect(creds.access_key_id).to eq('stubbed-akid')
expect(creds.secret_access_key).to eq('stubbed-secret')
end
it 'raises an error if stubbed_responses is not enabled' do
client = client_class.new(options.merge(stub_responses: false))
expect {
client.stub_responses(:example_operation, {})
}.to raise_error(/enable stubbing .* `:stub_responses => true`/)
end
it 'returns stubbed responses without making a request' do
client.stub_responses(:example_operation, string:'value')
resp = client.example_operation
expect(resp.string).to eq('value')
end
it 'accepts a list of stubs' do
client.stub_responses(:example_operation, [
{ string: 'value-1' },
{ string: 'value-2' },
])
expect(client.example_operation.string).to eq('value-1')
expect(client.example_operation.string).to eq('value-2')
end
it 'returns the same stub multiple times' do
client.stub_responses(:example_operation, string: 'fixed-value')
expect(client.example_operation.string).to eq('fixed-value')
expect(client.example_operation.string).to eq('fixed-value')
end
it 'returns the last stub after mulitple times' do
client.stub_responses(:example_operation, [
{ string: 'value-1' },
{ string: 'value-2' },
])
expect(client.example_operation.string).to eq('value-1')
expect(client.example_operation.string).to eq('value-2')
expect(client.example_operation.string).to eq('value-2')
end
it 'can stub errors' do
client.stub_responses(:example_operation, [
'NotFound',
StandardError,
RuntimeError.new('oops')
])
expect {
client.example_operation
}.to raise_error(client_class.errors_module::NotFound, 'stubbed-response-error-message')
expect {
client.example_operation
}.to raise_error(StandardError)
expect {
client.example_operation
}.to raise_error(RuntimeError, 'oops')
end
it 'can stub errors and data' do
client.stub_responses(:example_operation, ['NotFound', {}])
expect {
client.example_operation
}.to raise_error(client_class.errors_module::NotFound)
expect(client.example_operation.data.to_h).to eq({})
end
it 'accepts stubs given to the constructor' do
client = client_class.new(stub_responses: {
example_operation: { string: 'value' }
})
expect(client.example_operation.string).to eq('value')
end
context 'api requests' do
ApiRequestsStubbingExample = ApiHelper.sample_rest_xml
let(:client_class) { ApiRequestsStubbingExample.const_get(:Client) }
let(:client) { client_class.new(options) }
it 'allows api requests to be logged when stubbed' do
expect(client.api_requests.empty?).to be(true)
client.create_bucket(bucket:'aws-sdk')
expect(client.api_requests.length).to eq(1)
log_obj = client.api_requests[0]
expect(log_obj[:operation_name]).to eq(:create_bucket)
expect(log_obj[:params]).to eq({:bucket=>"aws-sdk"})
expect(log_obj[:context].metadata).to eq({
:gem_name=>"aws-sdk-sampleapi2",
:gem_version=>"1.0.0",
:response_target=>nil,
:original_params=>{:bucket=>"aws-sdk"},
:request_id=>"stubbed-request-id"
})
end
it 'raises an error when accessing api requests of a non stubbed client' do
client = client_class.new(options.merge(stub_responses: false))
expect {
client.api_requests
}.to raise_error(NotImplementedError)
end
end
end
end
end