|
| 1 | +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. |
| 2 | + |
| 3 | +#include <vespa/searchcore/proton/matching/ann_deadline_configuration.h> |
| 4 | +#include <vespa/vespalib/gtest/gtest.h> |
| 5 | +#include <vespa/vespalib/util/doom.h> |
| 6 | +#include <vespa/vespalib/util/time.h> |
| 7 | +#include <cstdint> |
| 8 | + |
| 9 | +using proton::matching::AnnDeadlineConfiguration; |
| 10 | +using vespalib::Deadline; |
| 11 | +using vespalib::Doom; |
| 12 | +using vespalib::steady_time; |
| 13 | + |
| 14 | +class AnnDeadlineConfigurationTest : public ::testing::Test { |
| 15 | +protected: |
| 16 | + std::atomic<steady_time> time; |
| 17 | + Doom doom; |
| 18 | + |
| 19 | +public: |
| 20 | + AnnDeadlineConfigurationTest(); |
| 21 | + ~AnnDeadlineConfigurationTest() override; |
| 22 | + |
| 23 | +}; |
| 24 | + |
| 25 | +AnnDeadlineConfigurationTest::AnnDeadlineConfigurationTest() |
| 26 | + : time(vespalib::steady_clock::now()), |
| 27 | + doom(time, time.load() + 1s) { |
| 28 | +} |
| 29 | + |
| 30 | +AnnDeadlineConfigurationTest::~AnnDeadlineConfigurationTest() = default; |
| 31 | + |
| 32 | +TEST_F(AnnDeadlineConfigurationTest, soft_doom_becomes_deadline) { |
| 33 | + for (auto duration : {50ms, 100ms, 1000ms}) { |
| 34 | + AnnDeadlineConfiguration config(time.load() + duration); |
| 35 | + |
| 36 | + for (uint32_t remaining_searches : {1, 2, 3, 5, 10}) { |
| 37 | + Deadline deadline = config.make_ann_deadline(doom, remaining_searches); |
| 38 | + EXPECT_EQ(Deadline::Type::BUDGET, deadline.type()); |
| 39 | + EXPECT_EQ(duration, deadline.time_left()); |
| 40 | + } |
| 41 | + } |
| 42 | +} |
| 43 | + |
| 44 | +TEST_F(AnnDeadlineConfigurationTest, ann_timebudget_becomes_deadline) { |
| 45 | + for (auto budget : {50ms, 100ms, 1000ms}) { |
| 46 | + for (auto ann_timeout : {10ms, 20ms, 70ms, 500ms}) { // timeout disabled, acts as soft-timeout |
| 47 | + AnnDeadlineConfiguration config(budget, false, time.load() + ann_timeout); |
| 48 | + |
| 49 | + for (uint32_t remaining_searches : {1, 2, 3, 5, 10}) { |
| 50 | + Deadline deadline = config.make_ann_deadline(doom, remaining_searches); |
| 51 | + EXPECT_EQ(Deadline::Type::BUDGET, deadline.type()); |
| 52 | + EXPECT_EQ(std::min(budget, ann_timeout), deadline.time_left()); |
| 53 | + } |
| 54 | + } |
| 55 | + } |
| 56 | +} |
| 57 | + |
| 58 | +TEST_F(AnnDeadlineConfigurationTest, ann_timeout_becomes_deadline) { |
| 59 | + for (auto ann_timeout : {10ms, 20ms, 80ms, 500ms}) { // Less than time budget of 2s |
| 60 | + AnnDeadlineConfiguration config(2s, true, time.load() + ann_timeout); |
| 61 | + |
| 62 | + for (uint32_t remaining_searches : {1, 2, 5, 10}) { |
| 63 | + Deadline deadline = config.make_ann_deadline(doom, remaining_searches); |
| 64 | + EXPECT_EQ(Deadline::Type::TIMEOUT, deadline.type()); |
| 65 | + EXPECT_EQ(ann_timeout / remaining_searches, deadline.time_left()); |
| 66 | + } |
| 67 | + } |
| 68 | +} |
| 69 | + |
| 70 | +TEST_F(AnnDeadlineConfigurationTest, ann_budget_ann_timeout_interaction_is_handled) { |
| 71 | + AnnDeadlineConfiguration config(50ms, true, time.load() + 100ms); |
| 72 | + Deadline deadline = config.make_ann_deadline(doom, 1); |
| 73 | + EXPECT_EQ(Deadline::Type::BUDGET, deadline.type()); |
| 74 | + EXPECT_EQ(50ms, deadline.time_left()); |
| 75 | + |
| 76 | + Deadline deadline2 = config.make_ann_deadline(doom, 2); |
| 77 | + EXPECT_EQ(Deadline::Type::TIMEOUT, deadline2.type()); |
| 78 | + EXPECT_EQ(50ms, deadline2.time_left()); |
| 79 | + |
| 80 | + Deadline deadline3 = config.make_ann_deadline(doom, 4); |
| 81 | + EXPECT_EQ(Deadline::Type::TIMEOUT, deadline3.type()); |
| 82 | + EXPECT_EQ(25ms, deadline3.time_left()); |
| 83 | + |
| 84 | + |
| 85 | + time.store(time.load() + 50ms); |
| 86 | + Deadline deadline4 = config.make_ann_deadline(doom, 1); |
| 87 | + EXPECT_EQ(Deadline::Type::TIMEOUT, deadline4.type()); |
| 88 | + EXPECT_EQ(50ms, deadline4.time_left()); |
| 89 | + |
| 90 | + Deadline deadline5 = config.make_ann_deadline(doom, 2); |
| 91 | + EXPECT_EQ(Deadline::Type::TIMEOUT, deadline5.type()); |
| 92 | + EXPECT_EQ(25ms, deadline5.time_left()); |
| 93 | +} |
| 94 | + |
| 95 | +GTEST_MAIN_RUN_ALL_TESTS() |
0 commit comments