Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / test_pageset.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 #include "gtest/gtest.h"
4
5 #include "os/memstore/PageSet.h"
6
7 template <typename T>
8 bool is_aligned(T* ptr) {
9   const auto align_mask = alignof(T) - 1;
10   return (reinterpret_cast<uintptr_t>(ptr) & align_mask) == 0;
11 }
12
13 TEST(PageSet, AllocAligned)
14 {
15   PageSet pages(1);
16   PageSet::page_vector range;
17
18   pages.alloc_range(0, 4, range);
19   ASSERT_EQ(4u, range.size());
20   ASSERT_EQ(0u, range[0]->offset);
21   ASSERT_EQ(1u, range[1]->offset);
22   ASSERT_EQ(2u, range[2]->offset);
23   ASSERT_EQ(3u, range[3]->offset);
24
25   // verify that the Page pointers are properly aligned
26   ASSERT_TRUE(is_aligned(range[0].get()));
27   ASSERT_TRUE(is_aligned(range[1].get()));
28   ASSERT_TRUE(is_aligned(range[2].get()));
29   ASSERT_TRUE(is_aligned(range[3].get()));
30 }
31
32 TEST(PageSet, AllocUnaligned)
33 {
34   PageSet pages(2);
35   PageSet::page_vector range;
36
37   // front of first page
38   pages.alloc_range(0, 1, range);
39   ASSERT_EQ(1u, range.size());
40   ASSERT_EQ(0u, range[0]->offset);
41   range.clear();
42
43   // back of first page
44   pages.alloc_range(1, 1, range);
45   ASSERT_EQ(1u, range.size());
46   ASSERT_EQ(0u, range[0]->offset);
47   range.clear();
48
49   // back of first page and front of second
50   pages.alloc_range(1, 2, range);
51   ASSERT_EQ(2u, range.size());
52   ASSERT_EQ(0u, range[0]->offset);
53   ASSERT_EQ(2u, range[1]->offset);
54   range.clear();
55
56   // back of first page and all of second
57   pages.alloc_range(1, 3, range);
58   ASSERT_EQ(2u, range.size());
59   ASSERT_EQ(0u, range[0]->offset);
60   ASSERT_EQ(2u, range[1]->offset);
61   range.clear();
62
63   // back of first page, all of second, and front of third
64   pages.alloc_range(1, 4, range);
65   ASSERT_EQ(3u, range.size());
66   ASSERT_EQ(0u, range[0]->offset);
67   ASSERT_EQ(2u, range[1]->offset);
68   ASSERT_EQ(4u, range[2]->offset);
69 }
70
71 TEST(PageSet, GetAligned)
72 {
73   // allocate 4 pages
74   PageSet pages(1);
75   PageSet::page_vector range;
76   pages.alloc_range(0, 4, range);
77   range.clear();
78
79   // get first page
80   pages.get_range(0, 1, range);
81   ASSERT_EQ(1u, range.size());
82   ASSERT_EQ(0u, range[0]->offset);
83   range.clear();
84
85   // get second and third pages
86   pages.get_range(1, 2, range);
87   ASSERT_EQ(2u, range.size());
88   ASSERT_EQ(1u, range[0]->offset);
89   ASSERT_EQ(2u, range[1]->offset);
90   range.clear();
91
92   // get all four pages
93   pages.get_range(0, 4, range);
94   ASSERT_EQ(4u, range.size());
95   ASSERT_EQ(0u, range[0]->offset);
96   ASSERT_EQ(1u, range[1]->offset);
97   ASSERT_EQ(2u, range[2]->offset);
98   ASSERT_EQ(3u, range[3]->offset);
99   range.clear();
100 }
101
102 TEST(PageSet, GetUnaligned)
103 {
104   // allocate 3 pages
105   PageSet pages(2);
106   PageSet::page_vector range;
107   pages.alloc_range(0, 6, range);
108   range.clear();
109
110   // front of first page
111   pages.get_range(0, 1, range);
112   ASSERT_EQ(1u, range.size());
113   ASSERT_EQ(0u, range[0]->offset);
114   range.clear();
115
116   // back of first page
117   pages.get_range(1, 1, range);
118   ASSERT_EQ(1u, range.size());
119   ASSERT_EQ(0u, range[0]->offset);
120   range.clear();
121
122   // back of first page and front of second
123   pages.get_range(1, 2, range);
124   ASSERT_EQ(2u, range.size());
125   ASSERT_EQ(0u, range[0]->offset);
126   ASSERT_EQ(2u, range[1]->offset);
127   range.clear();
128
129   // back of first page and all of second
130   pages.get_range(1, 3, range);
131   ASSERT_EQ(2u, range.size());
132   ASSERT_EQ(0u, range[0]->offset);
133   ASSERT_EQ(2u, range[1]->offset);
134   range.clear();
135
136   // back of first page, all of second, and front of third
137   pages.get_range(1, 4, range);
138   ASSERT_EQ(3u, range.size());
139   ASSERT_EQ(0u, range[0]->offset);
140   ASSERT_EQ(2u, range[1]->offset);
141   ASSERT_EQ(4u, range[2]->offset);
142   range.clear();
143
144   // back of third page with nothing beyond
145   pages.get_range(5, 999, range);
146   ASSERT_EQ(1u, range.size());
147   ASSERT_EQ(4u, range[0]->offset);
148   range.clear();
149 }
150
151 TEST(PageSet, GetHoles)
152 {
153   // allocate pages at offsets 1, 2, 5, and 7
154   PageSet pages(1);
155   PageSet::page_vector range;
156   for (uint64_t i : {1, 2, 5, 7})
157     pages.alloc_range(i, 1, range);
158   range.clear();
159
160   // nothing at offset 0, page at offset 1
161   pages.get_range(0, 2, range);
162   ASSERT_EQ(1u, range.size());
163   ASSERT_EQ(1u, range[0]->offset);
164   range.clear();
165
166   // nothing at offset 0, pages at offset 1 and 2, nothing at offset 3
167   pages.get_range(0, 4, range);
168   ASSERT_EQ(2u, range.size());
169   ASSERT_EQ(1u, range[0]->offset);
170   ASSERT_EQ(2u, range[1]->offset);
171   range.clear();
172
173   // page at offset 2, nothing at offset 3 or 4
174   pages.get_range(2, 3, range);
175   ASSERT_EQ(1u, range.size());
176   ASSERT_EQ(2u, range[0]->offset);
177   range.clear();
178
179   // get the full range
180   pages.get_range(0, 999, range);
181   ASSERT_EQ(4u, range.size());
182   ASSERT_EQ(1u, range[0]->offset);
183   ASSERT_EQ(2u, range[1]->offset);
184   ASSERT_EQ(5u, range[2]->offset);
185   ASSERT_EQ(7u, range[3]->offset);
186   range.clear();
187 }
188
189 TEST(PageSet, FreeAligned)
190 {
191   // allocate 4 pages
192   PageSet pages(1);
193   PageSet::page_vector range;
194   pages.alloc_range(0, 4, range);
195   range.clear();
196
197   // get the full range
198   pages.get_range(0, 4, range);
199   ASSERT_EQ(4u, range.size());
200   range.clear();
201
202   // free after offset 4 has no effect
203   pages.free_pages_after(4);
204   pages.get_range(0, 4, range);
205   ASSERT_EQ(4u, range.size());
206   range.clear();
207
208   // free page 4
209   pages.free_pages_after(3);
210   pages.get_range(0, 4, range);
211   ASSERT_EQ(3u, range.size());
212   range.clear();
213
214   // free pages 2 and 3
215   pages.free_pages_after(1);
216   pages.get_range(0, 4, range);
217   ASSERT_EQ(1u, range.size());
218   range.clear();
219 }
220
221 TEST(PageSet, FreeUnaligned)
222 {
223   // allocate 4 pages
224   PageSet pages(2);
225   PageSet::page_vector range;
226   pages.alloc_range(0, 8, range);
227   range.clear();
228
229   // get the full range
230   pages.get_range(0, 8, range);
231   ASSERT_EQ(4u, range.size());
232   range.clear();
233
234   // free after offset 7 has no effect
235   pages.free_pages_after(7);
236   pages.get_range(0, 8, range);
237   ASSERT_EQ(4u, range.size());
238   range.clear();
239
240   // free page 4
241   pages.free_pages_after(5);
242   pages.get_range(0, 8, range);
243   ASSERT_EQ(3u, range.size());
244   range.clear();
245
246   // free pages 2 and 3
247   pages.free_pages_after(1);
248   pages.get_range(0, 8, range);
249   ASSERT_EQ(1u, range.size());
250   range.clear();
251 }
252
253 TEST(PageSet, FreeHoles)
254 {
255   // allocate pages at offsets 1, 2, 5, and 7
256   PageSet pages(1);
257   PageSet::page_vector range;
258   for (uint64_t i : {1, 2, 5, 7})
259     pages.alloc_range(i, 1, range);
260   range.clear();
261
262   // get the full range
263   pages.get_range(0, 8, range);
264   ASSERT_EQ(4u, range.size());
265   range.clear();
266
267   // free page 7
268   pages.free_pages_after(6);
269   pages.get_range(0, 8, range);
270   ASSERT_EQ(3u, range.size());
271   range.clear();
272
273   // free page 5
274   pages.free_pages_after(3);
275   pages.get_range(0, 8, range);
276   ASSERT_EQ(2u, range.size());
277   range.clear();
278
279   // free pages 1 and 2
280   pages.free_pages_after(0);
281   pages.get_range(0, 8, range);
282   ASSERT_EQ(0u, range.size());
283 }