@@ -3,13 +3,9 @@ package middleware_test
3
3
import (
4
4
"bytes"
5
5
"context"
6
- "fmt"
7
- "github.com/aws/aws-sdk-go-v2/aws"
8
- "github.com/aws/aws-sdk-go-v2/aws/retry"
9
6
"net/http"
10
7
"reflect"
11
8
"strings"
12
- "sync/atomic"
13
9
"testing"
14
10
"time"
15
11
@@ -191,239 +187,3 @@ func TestAttemptClockSkewHandler(t *testing.T) {
191
187
})
192
188
}
193
189
}
194
-
195
- type HTTPClient interface {
196
- Do (* http.Request ) (* http.Response , error )
197
- }
198
-
199
- type Options struct {
200
- HTTPClient HTTPClient
201
- RetryMode aws.RetryMode
202
- Retryer aws.Retryer
203
- Offset * atomic.Int64
204
- }
205
-
206
- type MockClient struct {
207
- options Options
208
- }
209
-
210
- func addRetry (stack * smithymiddleware.Stack , o Options ) error {
211
- attempt := retry .NewAttemptMiddleware (o .Retryer , smithyhttp .RequestCloner , func (m * retry.Attempt ) {
212
- m .LogAttempts = false
213
- })
214
- return stack .Finalize .Add (attempt , smithymiddleware .After )
215
- }
216
-
217
- func addOffset (stack * smithymiddleware.Stack , o Options ) error {
218
- buildOffset := middleware.AddTimeOffsetBuildMiddleware {Offset : o .Offset }
219
- deserializeOffset := middleware.AddTimeOffsetDeserializeMiddleware {Offset : o .Offset }
220
- err := stack .Build .Add (& buildOffset , smithymiddleware .After )
221
- if err != nil {
222
- return err
223
- }
224
- err = stack .Deserialize .Add (& deserializeOffset , smithymiddleware .Before )
225
- if err != nil {
226
- return err
227
- }
228
- return nil
229
- }
230
-
231
- // Middleware to set a `Date` object that includes sdk time and offset
232
- type MockAddDateHeader struct {
233
- }
234
-
235
- func (l * MockAddDateHeader ) ID () string {
236
- return "MockAddDateHeader"
237
- }
238
-
239
- func (l * MockAddDateHeader ) HandleFinalize (
240
- ctx context.Context , in smithymiddleware.FinalizeInput , next smithymiddleware.FinalizeHandler ,
241
- ) (
242
- out smithymiddleware.FinalizeOutput , metadata smithymiddleware.Metadata , attemptError error ,
243
- ) {
244
- req := in .Request .(* smithyhttp.Request )
245
- date := sdk .NowTime ()
246
- skew := middleware .GetAttemptSkewContext (ctx )
247
- date = date .Add (skew )
248
- req .Header .Set ("Date" , date .Format (time .RFC850 ))
249
- return next .HandleFinalize (ctx , in )
250
- }
251
-
252
- // Middleware to deserialize the response which just says "OK" if the response is 200
253
- type DeserializeFailIfNotHTTP200 struct {
254
- }
255
-
256
- func (* DeserializeFailIfNotHTTP200 ) ID () string {
257
- return "DeserializeFailIfNotHTTP200"
258
- }
259
-
260
- func (m * DeserializeFailIfNotHTTP200 ) HandleDeserialize (ctx context.Context , in smithymiddleware.DeserializeInput , next smithymiddleware.DeserializeHandler ) (
261
- out smithymiddleware.DeserializeOutput , metadata smithymiddleware.Metadata , err error ,
262
- ) {
263
- out , metadata , err = next .HandleDeserialize (ctx , in )
264
- if err != nil {
265
- return out , metadata , err
266
- }
267
- response , ok := out .RawResponse .(* smithyhttp.Response )
268
- if ! ok {
269
- return out , metadata , fmt .Errorf ("expected raw response to be set on testing" )
270
- }
271
- if response .StatusCode != 200 {
272
- return out , metadata , mockRetryableError {true }
273
- }
274
- return out , metadata , err
275
- }
276
-
277
- func (c * MockClient ) setupMiddleware (stack * smithymiddleware.Stack ) error {
278
- err := error (nil )
279
- if c .options .Retryer != nil {
280
- err = addRetry (stack , c .options )
281
- if err != nil {
282
- return err
283
- }
284
- }
285
- if c .options .Offset != nil {
286
- err = addOffset (stack , c .options )
287
- if err != nil {
288
- return err
289
- }
290
- }
291
- err = stack .Finalize .Add (& MockAddDateHeader {}, smithymiddleware .After )
292
- if err != nil {
293
- return err
294
- }
295
- err = middleware .AddRecordResponseTiming (stack )
296
- if err != nil {
297
- return err
298
- }
299
- err = stack .Deserialize .Add (& DeserializeFailIfNotHTTP200 {}, smithymiddleware .After )
300
- if err != nil {
301
- return err
302
- }
303
- return nil
304
- }
305
-
306
- func (c * MockClient ) Do (ctx context.Context ) (interface {}, error ) {
307
- // setup middlewares
308
- ctx = smithymiddleware .ClearStackValues (ctx )
309
- stack := smithymiddleware .NewStack ("stack" , smithyhttp .NewStackRequest )
310
- err := c .setupMiddleware (stack )
311
- if err != nil {
312
- return nil , err
313
- }
314
- handler := smithymiddleware .DecorateHandler (smithyhttp .NewClientHandler (c .options .HTTPClient ), stack )
315
- result , _ , err := handler .Handle (ctx , 1 )
316
- if err != nil {
317
- return nil , err
318
- }
319
- return result , err
320
- }
321
-
322
- type mockRetryableError struct { b bool }
323
-
324
- func (m mockRetryableError ) RetryableError () bool { return m .b }
325
- func (m mockRetryableError ) Error () string {
326
- return fmt .Sprintf ("mock retryable %t" , m .b )
327
- }
328
-
329
- func failRequestIfSkewed () smithyhttp.ClientDoFunc {
330
- return func (req * http.Request ) (* http.Response , error ) {
331
- dateHeader := req .Header .Get ("Date" )
332
- if dateHeader == "" {
333
- return nil , fmt .Errorf ("expected `Date` header to be set" )
334
- }
335
- reqDate , err := time .Parse (time .RFC850 , dateHeader )
336
- if err != nil {
337
- return nil , err
338
- }
339
- parsedReqTime := time .Now ().Sub (reqDate )
340
- parsedReqTime = time .Duration .Abs (parsedReqTime )
341
- thresholdForSkewError := 4 * time .Minute
342
- if thresholdForSkewError - parsedReqTime <= 0 {
343
- return & http.Response {
344
- StatusCode : 403 ,
345
- Header : http.Header {
346
- "Date" : {time .Now ().Format (time .RFC850 )},
347
- },
348
- }, nil
349
- }
350
- // else, return OK
351
- return & http.Response {
352
- StatusCode : 200 ,
353
- Header : http.Header {},
354
- }, nil
355
- }
356
- }
357
-
358
- func TestSdkOffsetIsSet (t * testing.T ) {
359
- nowTime := sdk .NowTime
360
- defer func () {
361
- sdk .NowTime = nowTime
362
- }()
363
- fiveMinuteSkew := func () time.Time {
364
- return time .Now ().Add (5 * time .Minute )
365
- }
366
- sdk .NowTime = fiveMinuteSkew
367
- c := MockClient {
368
- Options {
369
- HTTPClient : failRequestIfSkewed (),
370
- },
371
- }
372
- resp , err := c .Do (context .Background ())
373
- if err == nil {
374
- t .Errorf ("Expected first request to fail since clock skew logic has not run. Got %v and err %v" , resp , err )
375
- }
376
- }
377
-
378
- func TestRetrySetsSkewInContext (t * testing.T ) {
379
- defer resetDefaults (sdk .TestingUseNopSleep ())
380
- fiveMinuteSkew := func () time.Time {
381
- return time .Now ().Add (5 * time .Minute )
382
- }
383
- sdk .NowTime = fiveMinuteSkew
384
- c := MockClient {
385
- Options {
386
- HTTPClient : failRequestIfSkewed (),
387
- Retryer : retry .NewStandard (func (s * retry.StandardOptions ) {
388
- }),
389
- },
390
- }
391
- resp , err := c .Do (context .Background ())
392
- if err != nil {
393
- t .Errorf ("Expected request to succeed on retry. Got %v and err %v" , resp , err )
394
- }
395
- }
396
-
397
- func TestSkewIsSetOnTheWholeClient (t * testing.T ) {
398
- defer resetDefaults (sdk .TestingUseNopSleep ())
399
- fiveMinuteSkew := func () time.Time {
400
- return time .Now ().Add (5 * time .Minute )
401
- }
402
- sdk .NowTime = fiveMinuteSkew
403
- var offset atomic.Int64
404
- offset .Store (0 )
405
- c := MockClient {
406
- Options {
407
- HTTPClient : failRequestIfSkewed (),
408
- Retryer : retry .NewStandard (func (s * retry.StandardOptions ) {
409
- }),
410
- Offset : & offset ,
411
- },
412
- }
413
- resp , err := c .Do (context .Background ())
414
- if err != nil {
415
- t .Errorf ("Expected request to succeed on retry. Got %v and err %v" , resp , err )
416
- }
417
- // Remove retryer so it has to succeed on first call
418
- c .options .Retryer = nil
419
- // same client, new request
420
- resp , err = c .Do (context .Background ())
421
- if err != nil {
422
- t .Errorf ("Expected second request to succeed since the skew should be set on the client. Got %v and err %v" , resp , err )
423
- }
424
- }
425
-
426
- func resetDefaults (restoreSleepFunc func ()) {
427
- sdk .NowTime = time .Now
428
- restoreSleepFunc ()
429
- }
0 commit comments