feat: Dosguard API weights (#2082)

Experimental support for Dosguard API weights.
This commit is contained in:
Sergey Kuznetsov
2025-05-13 15:02:21 +01:00
committed by GitHub
parent d02da5d28a
commit b87b32db86
42 changed files with 1653 additions and 329 deletions

View File

@@ -23,11 +23,15 @@
#include "util/newconfig/ConfigValue.hpp"
#include "util/newconfig/Types.hpp"
#include "web/dosguard/DOSGuard.hpp"
#include "web/dosguard/WeightsInterface.hpp"
#include "web/dosguard/WhitelistHandlerInterface.hpp"
#include <boost/json/object.hpp>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <cstddef>
#include <string>
#include <string_view>
using namespace testing;
@@ -53,6 +57,9 @@ struct DOSGuardTest : NoLoggerFixture {
struct MockWhitelistHandler : WhitelistHandlerInterface {
MOCK_METHOD(bool, isWhiteListed, (std::string_view ip), (const));
};
struct MockWeights : WeightsInterface {
MOCK_METHOD(size_t, requestWeight, (boost::json::object const& cmd), (const, override));
};
ClioConfigDefinition cfg{
{{"dos_guard.max_fetches", ConfigValue{ConfigType::Integer}.defaultValue(100)},
@@ -61,7 +68,9 @@ struct DOSGuardTest : NoLoggerFixture {
{"dos_guard.whitelist", Array{ConfigValue{ConfigType::String}}}}
};
NiceMock<MockWhitelistHandler> whitelistHandler;
DOSGuard guard{cfg, whitelistHandler};
StrictMock<MockWeights> weightsMock;
DOSGuard guard{cfg, whitelistHandler, weightsMock};
boost::json::object const request;
};
TEST_F(DOSGuardTest, Whitelisting)
@@ -110,11 +119,20 @@ TEST_F(DOSGuardTest, ClearFetchCountOnTimer)
TEST_F(DOSGuardTest, RequestLimit)
{
EXPECT_TRUE(guard.request(kIP));
EXPECT_TRUE(guard.request(kIP));
EXPECT_TRUE(guard.request(kIP));
EXPECT_CALL(weightsMock, requestWeight(request)).WillOnce(Return(1));
EXPECT_TRUE(guard.request(kIP, request));
EXPECT_CALL(weightsMock, requestWeight(request)).WillOnce(Return(1));
EXPECT_TRUE(guard.request(kIP, request));
EXPECT_CALL(weightsMock, requestWeight(request)).WillOnce(Return(1));
EXPECT_TRUE(guard.request(kIP, request));
EXPECT_TRUE(guard.isOk(kIP));
EXPECT_FALSE(guard.request(kIP));
EXPECT_CALL(weightsMock, requestWeight(request)).WillOnce(Return(1));
EXPECT_FALSE(guard.request(kIP, request));
EXPECT_FALSE(guard.isOk(kIP));
guard.clear();
EXPECT_TRUE(guard.isOk(kIP)); // can request again
@@ -122,11 +140,20 @@ TEST_F(DOSGuardTest, RequestLimit)
TEST_F(DOSGuardTest, RequestLimitOnTimer)
{
EXPECT_TRUE(guard.request(kIP));
EXPECT_TRUE(guard.request(kIP));
EXPECT_TRUE(guard.request(kIP));
EXPECT_CALL(weightsMock, requestWeight(request)).WillOnce(Return(1));
EXPECT_TRUE(guard.request(kIP, request));
EXPECT_CALL(weightsMock, requestWeight(request)).WillOnce(Return(1));
EXPECT_TRUE(guard.request(kIP, request));
EXPECT_CALL(weightsMock, requestWeight(request)).WillOnce(Return(1));
EXPECT_TRUE(guard.request(kIP, request));
EXPECT_TRUE(guard.isOk(kIP));
EXPECT_FALSE(guard.request(kIP));
EXPECT_CALL(weightsMock, requestWeight(request)).WillOnce(Return(1));
EXPECT_FALSE(guard.request(kIP, request));
EXPECT_FALSE(guard.isOk(kIP));
guard.clear();
EXPECT_TRUE(guard.isOk(kIP)); // can request again