@@ -1143,6 +1143,113 @@ func TestClient_PostForm(t *testing.T) {
11431143 resp .Body .Close ()
11441144}
11451145
1146+ func TestBackoff_RateLimitLinearJitterBackoff (t * testing.T ) {
1147+ testCases := []struct {
1148+ name string
1149+ min time.Duration
1150+ max time.Duration
1151+ headers http.Header
1152+ responseCode int
1153+ expect time.Duration
1154+ }{
1155+ {
1156+ name : "429 no retry header" ,
1157+ min : time .Second ,
1158+ max : time .Second ,
1159+ headers : http.Header {},
1160+ responseCode : http .StatusTooManyRequests ,
1161+ expect : time .Second ,
1162+ },
1163+ {
1164+ name : "503 no retry header" ,
1165+ min : time .Second ,
1166+ max : time .Second ,
1167+ headers : http.Header {},
1168+ responseCode : http .StatusServiceUnavailable ,
1169+ expect : time .Second ,
1170+ },
1171+ {
1172+ name : "429 retry header" ,
1173+ min : time .Second ,
1174+ max : time .Second ,
1175+ headers : http.Header {
1176+ "Retry-After" : []string {"2" },
1177+ },
1178+ responseCode : http .StatusTooManyRequests ,
1179+ expect : 2 * time .Second ,
1180+ },
1181+ {
1182+ name : "503 retry header" ,
1183+ min : time .Second ,
1184+ max : time .Second ,
1185+ headers : http.Header {
1186+ "Retry-After" : []string {"2" },
1187+ },
1188+ responseCode : http .StatusServiceUnavailable ,
1189+ expect : 2 * time .Second ,
1190+ },
1191+ {
1192+ name : "502 ignore retry header" ,
1193+ min : time .Second ,
1194+ max : time .Second ,
1195+ headers : http.Header {
1196+ "Retry-After" : []string {"2" },
1197+ },
1198+ responseCode : http .StatusBadGateway ,
1199+ expect : time .Second ,
1200+ },
1201+ {
1202+ name : "502 no retry header" ,
1203+ min : time .Second ,
1204+ max : time .Second ,
1205+ headers : http.Header {},
1206+ responseCode : http .StatusBadGateway ,
1207+ expect : time .Second ,
1208+ },
1209+ {
1210+ name : "429 retry header with jitter" ,
1211+ min : time .Second ,
1212+ max : 5 * time .Second ,
1213+ headers : http.Header {
1214+ "Retry-After" : []string {"2" },
1215+ },
1216+ responseCode : http .StatusTooManyRequests ,
1217+ expect : 2 * time .Second ,
1218+ },
1219+ {
1220+ name : "429 retry header less than min" ,
1221+ min : 5 * time .Second ,
1222+ max : 10 * time .Second ,
1223+ headers : http.Header {
1224+ "Retry-After" : []string {"2" },
1225+ },
1226+ responseCode : http .StatusTooManyRequests ,
1227+ expect : 2 * time .Second ,
1228+ },
1229+ {
1230+ name : "429 retry header in range" ,
1231+ min : time .Second ,
1232+ max : 10 * time .Second ,
1233+ headers : http.Header {
1234+ "Retry-After" : []string {"2" },
1235+ },
1236+ responseCode : http .StatusTooManyRequests ,
1237+ expect : 2 * time .Second ,
1238+ },
1239+ }
1240+ for _ , tc := range testCases {
1241+ t .Run (tc .name , func (t * testing.T ) {
1242+ got := RateLimitLinearJitterBackoff (tc .min , tc .max , 0 , & http.Response {
1243+ StatusCode : tc .responseCode ,
1244+ Header : tc .headers ,
1245+ })
1246+ if got != tc .expect {
1247+ t .Fatalf ("expected %s, got %s" , tc .expect , got )
1248+ }
1249+ })
1250+ }
1251+ }
1252+
11461253func TestBackoff (t * testing.T ) {
11471254 type tcase struct {
11481255 min time.Duration
0 commit comments