1
16
17 package unit
18
19 import (
20 "context"
21 "testing"
22
23 "github.com/jarcoal/httpmock"
24 "github.com/okta/okta-sdk-golang/v2/okta"
25 "github.com/okta/okta-sdk-golang/v2/tests"
26 "github.com/stretchr/testify/require"
27 )
28
29 func Test_429_Will_Automatically_Retry(t *testing.T) {
30 httpmock.Activate()
31 defer httpmock.DeactivateAndReset()
32
33 ctx, client, err := tests.NewClient(context.TODO(), okta.WithCache(false))
34 require.NoError(t, err, "failed to create client")
35
36 httpmock.RegisterResponder("GET", "/api/v1/users",
37 tests.MockResponse(
38 tests.Mock429Response(),
39 tests.MockValidResponse(),
40 ),
41 )
42
43 _, resp, err := client.User.ListUsers(ctx, nil)
44 require.Nil(t, err, "Error should have been nil")
45 require.NotNil(t, resp, "Response was nil")
46
47 httpmock.GetTotalCallCount()
48 info := httpmock.GetCallCountInfo()
49 require.Equal(t, 2, info["GET /api/v1/users"], "did not make exactly 2 call to /api/v1/users")
50 }
51
52 func Test_Will_Stop_Retrying_Based_On_Max_Retry_Configuration(t *testing.T) {
53 httpmock.Activate()
54 defer httpmock.DeactivateAndReset()
55
56 ctx, client, err := tests.NewClient(context.TODO(), okta.WithRequestTimeout(0), okta.WithRateLimitMaxRetries(1))
57 require.NoError(t, err)
58
59 httpmock.RegisterResponder("GET", "/api/v1/users",
60 tests.MockResponse(
61 tests.Mock429Response(),
62 tests.Mock429Response(),
63 ),
64 )
65
66 _, _, err = client.User.ListUsers(ctx, nil)
67 require.NotNil(t, err, "error was nil, but should have told the user they reached their max retry limit")
68
69 httpmock.GetTotalCallCount()
70 info := httpmock.GetCallCountInfo()
71
72 require.False(t, info["GET /api/v1/users"] < 2, "should have done at least one retry call to /api/v1/users")
73 require.Equal(t, 2, info["GET /api/v1/users"], "should have thrown error after first retry to /api/v1/users")
74 }
75
76 func Test_Will_Handle_Backoff_Strategy_For_429(t *testing.T) {
77 httpmock.Activate()
78 defer httpmock.DeactivateAndReset()
79
80 ctx, client, err := tests.NewClient(context.TODO(), okta.WithRequestTimeout(1), okta.WithRateLimitMaxRetries(3))
81 require.NoError(t, err, "failed to create client")
82
83 httpmock.RegisterResponder("GET", "/api/v1/users",
84 tests.MockResponse(
85 tests.Mock429Response(),
86 tests.Mock429Response(),
87 tests.Mock429Response(),
88 tests.MockValidResponse(),
89 ),
90 )
91
92 _, _, err = client.User.ListUsers(ctx, nil)
93 require.NotNil(t, err, "error was nil, but should have told the user they reached their max retry limit")
94
95 httpmock.GetTotalCallCount()
96 info := httpmock.GetCallCountInfo()
97
98 require.Equal(t, 1, info["GET /api/v1/users"], "should have thrown error before first retry to /api/v1/users due to request timeout")
99 }
100
101 func Test_a_429_with_x_reset_header_throws_error(t *testing.T) {
102 httpmock.Activate()
103 defer httpmock.DeactivateAndReset()
104
105 ctx, client, err := tests.NewClient(context.TODO())
106 require.NoError(t, err, "failed to create client")
107
108 httpmock.RegisterResponder("GET", "/api/v1/users",
109 tests.MockResponse(
110 tests.Mock429ResponseNoResetHeader(),
111 ),
112 )
113
114 _, _, err = client.User.ListUsers(ctx, nil)
115
116 require.NotNil(t, err, "error should not be nil. It should let user know the reset header is required")
117 }
118
119 func Test_a_429_with_no_date_header_throws_error(t *testing.T) {
120 httpmock.Activate()
121 defer httpmock.DeactivateAndReset()
122
123 ctx, client, err := tests.NewClient(context.TODO())
124 require.NoError(t, err, "failed to create client")
125
126 httpmock.RegisterResponder("GET", "/api/v1/users",
127 tests.MockResponse(
128 tests.Mock429ResponseNoDateHeader(),
129 ),
130 )
131
132 _, _, err = client.User.ListUsers(ctx, nil)
133
134 require.NotNil(t, err, "error should not be nil. It should let user know the date header is required")
135 }
136
137 func Test_gets_the_correct_backoff_time(t *testing.T) {
138 backoff, err := okta.Get429BackoffTime(tests.Mock429Response())
139 require.NoError(t, err)
140
141 require.Equal(t, int64(2), backoff, "backoff time should have only been 1 second")
142 }
143
View as plain text