]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/osd/TestMClockScheduler.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / test / osd / TestMClockScheduler.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2
3 #include "gtest/gtest.h"
4
5 #include "global/global_context.h"
6 #include "global/global_init.h"
7 #include "common/common_init.h"
8
9 #include "osd/scheduler/mClockScheduler.h"
10 #include "osd/scheduler/OpSchedulerItem.h"
11
12 using namespace ceph::osd::scheduler;
13
14 int main(int argc, char **argv) {
15 std::vector<const char*> args(argv, argv+argc);
16 auto cct = global_init(nullptr, args, CEPH_ENTITY_TYPE_OSD,
17 CODE_ENVIRONMENT_UTILITY,
18 CINIT_FLAG_NO_DEFAULT_CONFIG_FILE);
19 common_init_finish(g_ceph_context);
20
21 ::testing::InitGoogleTest(&argc, argv);
22 return RUN_ALL_TESTS();
23 }
24
25
26 class mClockSchedulerTest : public testing::Test {
27 public:
28 mClockScheduler q;
29
30 uint64_t client1;
31 uint64_t client2;
32 uint64_t client3;
33
34 mClockSchedulerTest() :
35 q(g_ceph_context),
36 client1(1001),
37 client2(9999),
38 client3(100000001)
39 {}
40
41 struct MockDmclockItem : public PGOpQueueable {
42 op_scheduler_class scheduler_class;
43
44 MockDmclockItem(op_scheduler_class _scheduler_class) :
45 PGOpQueueable(spg_t()),
46 scheduler_class(_scheduler_class) {}
47
48 MockDmclockItem()
49 : MockDmclockItem(op_scheduler_class::background_best_effort) {}
50
51 op_type_t get_op_type() const final {
52 return op_type_t::client_op; // not used
53 }
54
55 ostream &print(ostream &rhs) const final { return rhs; }
56
57 std::optional<OpRequestRef> maybe_get_op() const final {
58 return std::nullopt;
59 }
60
61 op_scheduler_class get_scheduler_class() const final {
62 return scheduler_class;
63 }
64
65 void run(OSD *osd, OSDShard *sdata, PGRef& pg, ThreadPool::TPHandle &handle) final {}
66 };
67 };
68
69 template <typename... Args>
70 OpSchedulerItem create_item(
71 epoch_t e, uint64_t owner, Args&&... args)
72 {
73 return OpSchedulerItem(
74 std::make_unique<mClockSchedulerTest::MockDmclockItem>(
75 std::forward<Args>(args)...),
76 12, 12,
77 utime_t(), owner, e);
78 }
79
80 TEST_F(mClockSchedulerTest, TestEmpty) {
81 ASSERT_TRUE(q.empty());
82
83 q.enqueue(create_item(100, client1, op_scheduler_class::client));
84 q.enqueue(create_item(102, client1, op_scheduler_class::client));
85 q.enqueue(create_item(104, client1, op_scheduler_class::client));
86
87 ASSERT_FALSE(q.empty());
88
89 std::list<OpSchedulerItem> reqs;
90
91 reqs.push_back(q.dequeue());
92 reqs.push_back(q.dequeue());
93
94 ASSERT_FALSE(q.empty());
95
96 for (auto &&i : reqs) {
97 q.enqueue_front(std::move(i));
98 }
99 reqs.clear();
100
101 ASSERT_FALSE(q.empty());
102
103 for (int i = 0; i < 3; ++i) {
104 ASSERT_FALSE(q.empty());
105 q.dequeue();
106 }
107
108 ASSERT_TRUE(q.empty());
109 }
110
111 TEST_F(mClockSchedulerTest, TestSingleClientOrderedEnqueueDequeue) {
112 q.enqueue(create_item(100, client1));
113 q.enqueue(create_item(101, client1));
114 q.enqueue(create_item(102, client1));
115 q.enqueue(create_item(103, client1));
116 q.enqueue(create_item(104, client1));
117
118 auto r = q.dequeue();
119 ASSERT_EQ(100u, r.get_map_epoch());
120
121 r = q.dequeue();
122 ASSERT_EQ(101u, r.get_map_epoch());
123
124 r = q.dequeue();
125 ASSERT_EQ(102u, r.get_map_epoch());
126
127 r = q.dequeue();
128 ASSERT_EQ(103u, r.get_map_epoch());
129
130 r = q.dequeue();
131 ASSERT_EQ(104u, r.get_map_epoch());
132 }
133
134 TEST_F(mClockSchedulerTest, TestMultiClientOrderedEnqueueDequeue) {
135 const unsigned NUM = 1000;
136 for (unsigned i = 0; i < NUM; ++i) {
137 for (auto &&c: {client1, client2, client3}) {
138 q.enqueue(create_item(i, c));
139 }
140 }
141
142 std::map<uint64_t, epoch_t> next;
143 for (auto &&c: {client1, client2, client3}) {
144 next[c] = 0;
145 }
146 for (unsigned i = 0; i < NUM * 3; ++i) {
147 ASSERT_FALSE(q.empty());
148 auto r = q.dequeue();
149 auto owner = r.get_owner();
150 auto niter = next.find(owner);
151 ASSERT_FALSE(niter == next.end());
152 ASSERT_EQ(niter->second, r.get_map_epoch());
153 niter->second++;
154 }
155 ASSERT_TRUE(q.empty());
156 }