blob: 2c8c63e8f53f38a4240e4749263b42a5df5a2220 [file] [log] [blame]
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <process/clock.hpp>
#include <process/future.hpp>
#include <process/gtest.hpp>
#include <process/limiter.hpp>
#include <stout/duration.hpp>
#include <stout/nothing.hpp>
using process::Clock;
using process::Future;
using process::RateLimiter;
TEST(LimiterTest, Acquire)
{
int permits = 2;
Duration duration = Milliseconds(5);
RateLimiter limiter(permits, duration);
Milliseconds interval = duration / permits;
Clock::pause();
Future<Nothing> acquire1 = limiter.acquire();
Future<Nothing> acquire2 = limiter.acquire();
Future<Nothing> acquire3 = limiter.acquire();
AWAIT_READY(acquire1);
Clock::advance(interval);
AWAIT_READY(acquire2);
EXPECT_TRUE(acquire3.isPending());
Clock::advance(interval);
AWAIT_READY(acquire3);
}
// In this test 4 permits are given, but the 2nd permit's acquire
// is immediately discarded. So, 1st, 3rd and 4th permits should
// be acquired according to the rate limit.
TEST(LimiterTest, DiscardMiddle)
{
int permits = 2;
Duration duration = Milliseconds(5);
RateLimiter limiter(permits, duration);
Milliseconds interval = duration / permits;
Clock::pause();
Future<Nothing> acquire1 = limiter.acquire();
Future<Nothing> acquire2 = limiter.acquire();
Future<Nothing> acquire3 = limiter.acquire();
Future<Nothing> acquire4 = limiter.acquire();
AWAIT_READY(acquire1);
// Discard 'acquire2'.
acquire2.discard();
// 'acquire3' should be satisfied within one 'interval'.
Clock::advance(interval);
AWAIT_READY(acquire3);
// 'acquire2' should be in 'DISCARDED' state.
AWAIT_DISCARDED(acquire2);
// 'acquire4' should be satisfied after another 'interval'.
Clock::advance(interval);
AWAIT_READY(acquire4);
}
// In this test 2 permits are initially given, but the 2nd permit's
// future is immediately discarded. Then the 3rd permit is given. So,
// 1st and 3rd permits should be acquired according to the rate limit.
TEST(LimiterTest, DiscardLast)
{
int permits = 2;
Duration duration = Milliseconds(5);
RateLimiter limiter(permits, duration);
Milliseconds interval = duration / permits;
Clock::pause();
Future<Nothing> acquire1 = limiter.acquire();
Future<Nothing> acquire2 = limiter.acquire();
AWAIT_READY(acquire1);
// Discard 'acquire2'.
acquire2.discard();
// Now acquire 'acquire3'.
Future<Nothing> acquire3 = limiter.acquire();
// 'acquire3' should be satisfied within one 'interval'.
Clock::advance(interval);
AWAIT_READY(acquire3);
}