Что такое rate limiting
Что проверяют
Понимаете ли вы, зачем сервисы ограничивают частоту запросов, и, что важнее для тестировщика, умеете ли это проверять. Ограничение частоты редко описано в требованиях подробно, поэтому вопрос показывает, придумаете ли вы проверки для механизма, заданного одной строчкой.
Как отвечать
Ограничение частоты это лимит на число запросов за интервал по некоторому ключу: адресу, токену, учётной записи, методу. Цели три: защита от перебора паролей и выкачивания данных, честное распределение ресурса, предсказуемая нагрузка.
Алгоритмы стоит назвать своими именами. Фиксированное окно простое, но пропускает двойной всплеск на стыке двух окон. Скользящее окно ровнее и дороже. Токен-бакет допускает всплеск в пределах накопленной ёмкости. Дырявое ведро выравнивает поток на выходе.
Контракт ответа: код 429, заголовок Retry-After, заголовки с лимитом, остатком и моментом сброса. Код 503 означает недоступность и лимитом не является.
Что проверять: срабатывание ровно на границе и на единицу ниже, восстановление после окна, правильность ключа (лимит по токену не должен обходиться сменой адреса и наоборот), изоляцию методов друг от друга, поведение клиента после отказа, осмысленность тела ответа. Отдельно проверяется работа за прокси: без разбора заголовка с исходным адресом лимит считается на прокси, и целый оператор связи делит один счётчик.
Где спотыкаются
Проверяют только факт отказа и не проверяют возврат в норму. Сломанный сброс счётчика выглядит как работающий лимит ровно до момента, когда живой пользователь остаётся заблокированным до перезапуска сервиса.
Не изолируют тесты. Один сценарий выбирает лимит, соседние падают, команда записывает их в нестабильные и через неделю перестаёт смотреть на красное. Правильно либо отводить лимиту отдельный ключ и окружение, либо уметь сбрасывать счётчик перед прогоном.
Тестируют на одном экземпляре сервиса и переносят вывод на бой. Счётчик в памяти процесса при нескольких экземплярах даёт кратно больший фактический лимит, а распределённый счётчик без атомарной операции пропускает лишние запросы на границе окна. Такую разницу видно только на конфигурации, близкой к боевой.