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
|
test_that("has useful default (with message)", {
req <- request_test()
expect_snapshot(req <- req_retry(req))
expect_equal(retry_max_tries(req), 2)
expect_equal(retry_max_seconds(req), Inf)
})
test_that("can set define maximum retries", {
req <- request_test()
expect_equal(retry_max_tries(req), 1)
expect_equal(retry_max_seconds(req), Inf)
req <- req_retry(req, max_tries = 2)
expect_equal(retry_max_tries(req), 2)
expect_equal(retry_max_seconds(req), Inf)
req <- req_retry(req, max_seconds = 5)
expect_equal(retry_max_tries(req), Inf)
expect_equal(retry_max_seconds(req), 5)
req <- req_retry(req, max_tries = 2, max_seconds = 5)
expect_equal(retry_max_tries(req), 2)
expect_equal(retry_max_seconds(req), 5)
})
test_that("can override default is_transient", {
req <- request_test()
expect_equal(retry_is_transient(req, response(404)), FALSE)
expect_equal(retry_is_transient(req, response(429)), TRUE)
req <- req_retry(req, is_transient = ~ resp_status(.x) == 404)
expect_equal(retry_is_transient(req, response(404)), TRUE)
expect_equal(retry_is_transient(req, response(429)), FALSE)
})
test_that("can override default backoff", {
withr::local_seed(1014)
req <- request_test()
expect_equal(retry_backoff(req, 1), 1.1)
expect_equal(retry_backoff(req, 5), 26.9)
expect_equal(retry_backoff(req, 10), 60)
req <- req_retry(req, backoff = ~10)
expect_equal(retry_backoff(req, 1), 10)
expect_equal(retry_backoff(req, 5), 10)
expect_equal(retry_backoff(req, 10), 10)
})
test_that("can override default retry wait", {
resp <- response(429, headers = c("Retry-After: 10", "Wait-For: 20"))
req <- request_test()
expect_equal(retry_after(req, resp, 1), 10)
req <- req_retry(req, after = ~ as.numeric(resp_header(.x, "Wait-For")))
expect_equal(retry_after(req, resp, 1), 20)
})
test_that("missing retry-after uses backoff", {
req <- request_test()
req <- req_retry(req, backoff = ~10)
expect_equal(retry_after(req, response(429), 1), 10)
})
test_that("useful message if `after` wrong", {
req <- request_test() %>%
req_retry(
is_transient = function(resp) TRUE,
after = function(resp) resp
)
expect_snapshot(req_perform(req), error = TRUE)
})
test_that("validates its inputs", {
req <- new_request("http://example.com")
expect_snapshot(error = TRUE, {
req_retry(req, max_tries = 0)
req_retry(req, max_tries = 2, max_seconds = "x")
req_retry(req, max_tries = 2, retry_on_failure = "x")
})
})
test_that("is_number_or_na implemented correctly", {
expect_equal(is_number_or_na(1), TRUE)
expect_equal(is_number_or_na(NA_real_), TRUE)
expect_equal(is_number_or_na(NA), TRUE)
expect_equal(is_number_or_na(1:2), FALSE)
expect_equal(is_number_or_na(numeric()), FALSE)
expect_equal(is_number_or_na("x"), FALSE)
})
# circuit breaker --------------------------------------------------------
test_that("triggered after specified requests", {
req <- request_test("/status/:status", status = 429) %>%
req_retry(
after = function(resp) 0,
max_tries = 10,
failure_threshold = 1
)
# First attempt performs, retries, then errors
req_perform(req) %>%
expect_condition(class = "httr2_perform") %>%
expect_condition(class = "httr2_retry") %>%
expect_error(class = "httr2_breaker")
# Second attempt errors without performing
req_perform(req) %>%
expect_no_condition(class = "httr2_perform") %>%
expect_error(class = "httr2_breaker")
# Attempt on same realm errors without trying at all
req2 <- request_test("/status/:status", status = 200) %>%
req_retry()
req_perform(req) %>%
expect_no_condition(class = "httr2_perform") %>%
expect_error(class = "httr2_breaker")
})
|