aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib/src/tests/executor_idle_tracking/executor_idle_tracking_test.cpp
blob: c6e2d229a208a7dc141b6538ff1c8f9a82ff078f (plain) (blame)
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
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/vespalib/util/executor_idle_tracking.h>
#include <vespa/vespalib/gtest/gtest.h>

using namespace vespalib;

steady_time at(duration d) { return steady_time(d); }

TEST(ThreadIdleTrackingTest, can_track_idle_time) {
    ThreadIdleTracker state;
    EXPECT_FALSE(state.is_idle()); // starts in active state
    state.set_idle(at(50ms));
    EXPECT_TRUE(state.is_idle());
    EXPECT_EQ(count_ms(state.set_active(at(65ms))), 15);
    EXPECT_FALSE(state.is_idle());
    state.set_idle(at(100ms));
    EXPECT_TRUE(state.is_idle());
    EXPECT_EQ(count_ms(state.set_active(at(150ms))), 50);
    EXPECT_FALSE(state.is_idle());
}

TEST(ThreadIdleTrackingTest, redundant_set_idle_is_handled) {
    ThreadIdleTracker state;
    state.set_idle(at(50ms));
    state.set_idle(at(100ms));
    EXPECT_TRUE(state.is_idle());
    EXPECT_EQ(count_ms(state.set_active(at(150ms))), 100);
}

TEST(ThreadIdleTrackingTest, redundant_set_active_is_handled) {
    ThreadIdleTracker state;
    state.set_idle(at(50ms));
    EXPECT_EQ(count_ms(state.set_active(at(150ms))), 100);
    EXPECT_EQ(count_ms(state.set_active(at(200ms))), 0);
    EXPECT_FALSE(state.is_idle());
}

TEST(ThreadIdleTrackingTest, reset_consumes_idle_time_when_idle) {
    ThreadIdleTracker state;
    state.set_idle(at(50ms));
    EXPECT_EQ(count_ms(state.reset(at(100ms))), 50);
    EXPECT_TRUE(state.is_idle());
    EXPECT_EQ(count_ms(state.set_active(at(150ms))), 50);
}

TEST(ThreadIdleTrackingTest, reset_does_nothing_when_active) {
    ThreadIdleTracker state;
    EXPECT_EQ(count_ms(state.reset(at(100ms))), 0);
    EXPECT_FALSE(state.is_idle());
}

TEST(ExecutorIdleTrackingTest, can_calculate_idle_metric) {
    ExecutorIdleTracker state(at(100ms));
    state.was_idle(20ms);
    state.was_idle(5ms);
    state.was_idle(15ms);
    state.was_idle(3ms);
    state.was_idle(7ms); // 50 ms total idle
    EXPECT_EQ(state.reset(at(120ms), 5), 0.5); // 100 ms total time
    EXPECT_EQ(state.reset(at(140ms), 5), 0.0);
    state.was_idle(25ms);
    EXPECT_EQ(state.reset(at(160ms), 5), 0.25);
}

TEST(ExecutorIdleTrackingTest, avoids_idle_above_1) {
    ExecutorIdleTracker state(at(100ms));
    state.was_idle(100ms);
    EXPECT_EQ(state.reset(at(110ms), 1), 1.0);
}

TEST(ExecutorIdleTrackingTest, avoids_division_by_zero) {
    ExecutorIdleTracker state(at(100ms));
    EXPECT_EQ(state.reset(at(100ms), 1), 0.0);
    state.was_idle(10ms);
    EXPECT_EQ(state.reset(at(100ms), 1), 1.0);
}

GTEST_MAIN_RUN_ALL_TESTS()