]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/libradosstriper/aio.cc
bump version to 18.2.4-pve3
[ceph.git] / ceph / src / test / libradosstriper / aio.cc
1 #include "include/rados/librados.h"
2 #include "include/rados/librados.hpp"
3 #include "include/radosstriper/libradosstriper.h"
4 #include "include/radosstriper/libradosstriper.hpp"
5 #include "test/librados/test.h"
6 #include "test/libradosstriper/TestCase.h"
7
8 #include <boost/scoped_ptr.hpp>
9 #include <fcntl.h>
10 #include <semaphore.h>
11 #include <errno.h>
12
13 using namespace librados;
14 using namespace libradosstriper;
15 using std::pair;
16
17 class AioTestData
18 {
19 public:
20 AioTestData() : m_complete(false) {
21 sem_init(&m_sem, 0, 0);
22 }
23
24 ~AioTestData() {
25 sem_destroy(&m_sem);
26 }
27
28 void notify() {
29 sem_post(&m_sem);
30 }
31
32 void wait() {
33 sem_wait(&m_sem);
34 }
35
36 bool m_complete;
37
38 private:
39 sem_t m_sem;
40 };
41
42 void set_completion_complete(rados_completion_t cb, void *arg)
43 {
44 AioTestData *test = static_cast<AioTestData*>(arg);
45 test->m_complete = true;
46 test->notify();
47 }
48
49 TEST_F(StriperTest, SimpleWrite) {
50 AioTestData test_data;
51 rados_completion_t my_completion;
52 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
53 set_completion_complete,
54 &my_completion));
55 char buf[128];
56 memset(buf, 0xcc, sizeof(buf));
57 ASSERT_EQ(0, rados_striper_aio_write(striper, "StriperTest", my_completion, buf, sizeof(buf), 0));
58 TestAlarm alarm;
59 test_data.wait();
60 rados_aio_release(my_completion);
61 }
62
63 TEST_F(StriperTestPP, SimpleWritePP) {
64 AioTestData test_data;
65 AioCompletion *my_completion = librados::Rados::aio_create_completion
66 ((void*)&test_data, set_completion_complete);
67 char buf[128];
68 memset(buf, 0xcc, sizeof(buf));
69 bufferlist bl1;
70 bl1.append(buf, sizeof(buf));
71 ASSERT_EQ(0, striper.aio_write("SimpleWritePP", my_completion, bl1, sizeof(buf), 0));
72 TestAlarm alarm;
73 test_data.wait();
74 my_completion->release();
75 }
76
77 TEST_F(StriperTest, WaitForSafe) {
78 AioTestData test_data;
79 rados_completion_t my_completion;
80 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
81 set_completion_complete,
82 &my_completion));
83 char buf[128];
84 memset(buf, 0xcc, sizeof(buf));
85 ASSERT_EQ(0, rados_striper_aio_write(striper, "WaitForSafe", my_completion, buf, sizeof(buf), 0));
86 TestAlarm alarm;
87 rados_aio_wait_for_complete(my_completion);
88 test_data.wait();
89 rados_aio_release(my_completion);
90 }
91
92 TEST_F(StriperTestPP, WaitForSafePP) {
93 AioTestData test_data;
94 AioCompletion *my_completion =
95 librados::Rados::aio_create_completion(&test_data,
96 set_completion_complete);
97 char buf[128];
98 memset(buf, 0xcc, sizeof(buf));
99 bufferlist bl1;
100 bl1.append(buf, sizeof(buf));
101 ASSERT_EQ(0, striper.aio_write("WaitForSafePP", my_completion, bl1, sizeof(buf), 0));
102 TestAlarm alarm;
103 my_completion->wait_for_complete();
104 test_data.wait();
105 my_completion->release();
106 }
107
108 TEST_F(StriperTest, RoundTrip) {
109 AioTestData test_data;
110 rados_completion_t my_completion;
111 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
112 set_completion_complete,
113 &my_completion));
114 char buf[128];
115 memset(buf, 0xcc, sizeof(buf));
116 ASSERT_EQ(0, rados_striper_aio_write(striper, "RoundTrip", my_completion, buf, sizeof(buf), 0));
117 {
118 TestAlarm alarm;
119 test_data.wait();
120 }
121 char buf2[128];
122 memset(buf2, 0, sizeof(buf2));
123 rados_completion_t my_completion2;
124 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
125 set_completion_complete,
126 &my_completion2));
127 ASSERT_EQ(0, rados_striper_aio_read(striper, "RoundTrip", my_completion2, buf2, sizeof(buf2), 0));
128 {
129 TestAlarm alarm;
130 rados_aio_wait_for_complete(my_completion2);
131 }
132 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
133 test_data.wait();
134 rados_aio_release(my_completion);
135 rados_aio_release(my_completion2);
136 }
137
138 TEST_F(StriperTest, RoundTrip2) {
139 AioTestData test_data;
140 rados_completion_t my_completion;
141 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
142 set_completion_complete,
143 &my_completion));
144 char buf[128];
145 memset(buf, 0xcc, sizeof(buf));
146 ASSERT_EQ(0, rados_striper_aio_write(striper, "RoundTrip2", my_completion, buf, sizeof(buf), 0));
147 {
148 TestAlarm alarm;
149 test_data.wait();
150 }
151 char buf2[128];
152 memset(buf2, 0, sizeof(buf2));
153 rados_completion_t my_completion2;
154 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
155 set_completion_complete,
156 &my_completion2));
157 ASSERT_EQ(0, rados_striper_aio_read(striper, "RoundTrip2", my_completion2, buf2, sizeof(buf2), 0));
158 {
159 TestAlarm alarm;
160 rados_aio_wait_for_complete(my_completion2);
161 }
162 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
163 test_data.wait();
164 rados_aio_release(my_completion);
165 rados_aio_release(my_completion2);
166 }
167
168 TEST_F(StriperTestPP, RoundTripPP) {
169 AioTestData test_data;
170 AioCompletion *my_completion =
171 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
172 char buf[128];
173 memset(buf, 0xcc, sizeof(buf));
174 bufferlist bl1;
175 bl1.append(buf, sizeof(buf));
176 ASSERT_EQ(0, striper.aio_write("RoundTripPP", my_completion, bl1, sizeof(buf), 0));
177 {
178 TestAlarm alarm;
179 test_data.wait();
180 }
181 bufferlist bl2;
182 AioCompletion *my_completion2 =
183 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
184 ASSERT_EQ(0, striper.aio_read("RoundTripPP", my_completion2, &bl2, sizeof(buf), 0));
185 {
186 TestAlarm alarm;
187 my_completion2->wait_for_complete();
188 }
189 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
190 test_data.wait();
191 my_completion->release();
192 my_completion2->release();
193 }
194
195 TEST_F(StriperTestPP, RoundTripPP2) {
196 AioTestData test_data;
197 AioCompletion *my_completion =
198 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
199 char buf[128];
200 memset(buf, 0xcc, sizeof(buf));
201 bufferlist bl1;
202 bl1.append(buf, sizeof(buf));
203 ASSERT_EQ(0, striper.aio_write("RoundTripPP2", my_completion, bl1, sizeof(buf), 0));
204 {
205 TestAlarm alarm;
206 test_data.wait();
207 }
208 bufferlist bl2;
209 AioCompletion *my_completion2 =
210 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
211 ASSERT_EQ(0, striper.aio_read("RoundTripPP2", my_completion2, &bl2, sizeof(buf), 0));
212 {
213 TestAlarm alarm;
214 my_completion2->wait_for_complete();
215 }
216 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
217 test_data.wait();
218 my_completion->release();
219 my_completion2->release();
220 }
221
222 TEST_F(StriperTest, IsComplete) {
223 AioTestData test_data;
224 rados_completion_t my_completion;
225 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
226 set_completion_complete,
227 &my_completion));
228 char buf[128];
229 memset(buf, 0xcc, sizeof(buf));
230 ASSERT_EQ(0, rados_striper_aio_write(striper, "IsComplete", my_completion, buf, sizeof(buf), 0));
231 {
232 TestAlarm alarm;
233 test_data.wait();
234 }
235 char buf2[128];
236 memset(buf2, 0, sizeof(buf2));
237 rados_completion_t my_completion2;
238 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
239 set_completion_complete,
240 &my_completion2));
241 ASSERT_EQ(0, rados_striper_aio_read(striper, "IsComplete", my_completion2, buf2, sizeof(buf2), 0));
242 {
243 TestAlarm alarm;
244 // Busy-wait until the AIO completes.
245 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
246 while (true) {
247 int is_complete = rados_aio_is_complete(my_completion2);
248 if (is_complete)
249 break;
250 }
251 }
252 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
253 test_data.wait();
254 rados_aio_release(my_completion);
255 rados_aio_release(my_completion2);
256 }
257
258 TEST_F(StriperTestPP, IsCompletePP) {
259 AioTestData test_data;
260 AioCompletion *my_completion =
261 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
262 char buf[128];
263 memset(buf, 0xcc, sizeof(buf));
264 bufferlist bl1;
265 bl1.append(buf, sizeof(buf));
266 ASSERT_EQ(0, striper.aio_write("IsCompletePP", my_completion, bl1, sizeof(buf), 0));
267 {
268 TestAlarm alarm;
269 test_data.wait();
270 }
271 bufferlist bl2;
272 AioCompletion *my_completion2 =
273 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
274 ASSERT_EQ(0, striper.aio_read("IsCompletePP", my_completion2, &bl2, sizeof(buf), 0));
275 {
276 TestAlarm alarm;
277 // Busy-wait until the AIO completes.
278 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
279 while (true) {
280 int is_complete = my_completion2->is_complete();
281 if (is_complete)
282 break;
283 }
284 }
285 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
286 test_data.wait();
287 my_completion->release();
288 my_completion2->release();
289 }
290
291 TEST_F(StriperTest, IsSafe) {
292 AioTestData test_data;
293 rados_completion_t my_completion;
294 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
295 set_completion_complete,
296 &my_completion));
297 char buf[128];
298 memset(buf, 0xcc, sizeof(buf));
299 ASSERT_EQ(0, rados_striper_aio_write(striper, "IsSafe", my_completion, buf, sizeof(buf), 0));
300 {
301 TestAlarm alarm;
302 // Busy-wait until the AIO completes.
303 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
304 while (true) {
305 int is_safe = rados_aio_is_safe(my_completion);
306 if (is_safe)
307 break;
308 }
309 }
310 char buf2[128];
311 memset(buf2, 0, sizeof(buf2));
312 rados_completion_t my_completion2;
313 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
314 set_completion_complete,
315 &my_completion2));
316 ASSERT_EQ(0, rados_striper_aio_read(striper, "IsSafe", my_completion2, buf2, sizeof(buf2), 0));
317 {
318 TestAlarm alarm;
319 rados_aio_wait_for_complete(my_completion2);
320 }
321 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
322 test_data.wait();
323 rados_aio_release(my_completion);
324 rados_aio_release(my_completion2);
325 }
326
327 TEST_F(StriperTest, RoundTripAppend) {
328 AioTestData test_data;
329 rados_completion_t my_completion, my_completion2, my_completion3;
330 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
331 set_completion_complete,
332 &my_completion));
333 char buf[128];
334 memset(buf, 0xcc, sizeof(buf));
335 ASSERT_EQ(0, rados_striper_aio_append(striper, "RoundTripAppend", my_completion, buf, sizeof(buf)));
336 {
337 TestAlarm alarm;
338 rados_aio_wait_for_complete(my_completion);
339 }
340 char buf2[128];
341 memset(buf2, 0xdd, sizeof(buf2));
342 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
343 set_completion_complete,
344 &my_completion2));
345 ASSERT_EQ(0, rados_striper_aio_append(striper, "RoundTripAppend", my_completion2, buf2, sizeof(buf)));
346 {
347 TestAlarm alarm;
348 rados_aio_wait_for_complete(my_completion2);
349 }
350 char buf3[sizeof(buf) + sizeof(buf2)];
351 memset(buf3, 0, sizeof(buf3));
352 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
353 set_completion_complete,
354 &my_completion3));
355 ASSERT_EQ(0, rados_striper_aio_read(striper, "RoundTripAppend", my_completion3, buf3, sizeof(buf3), 0));
356 {
357 TestAlarm alarm;
358 rados_aio_wait_for_complete(my_completion3);
359 }
360 ASSERT_EQ((int)(sizeof(buf) + sizeof(buf2)), rados_aio_get_return_value(my_completion3));
361 ASSERT_EQ(0, memcmp(buf3, buf, sizeof(buf)));
362 ASSERT_EQ(0, memcmp(buf3 + sizeof(buf), buf2, sizeof(buf2)));
363 test_data.wait();
364 rados_aio_release(my_completion);
365 rados_aio_release(my_completion2);
366 rados_aio_release(my_completion3);
367 }
368
369 TEST_F(StriperTestPP, RoundTripAppendPP) {
370 AioTestData test_data;
371 AioCompletion *my_completion =
372 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
373 char buf[128];
374 memset(buf, 0xcc, sizeof(buf));
375 bufferlist bl1;
376 bl1.append(buf, sizeof(buf));
377 ASSERT_EQ(0, striper.aio_append("RoundTripAppendPP", my_completion, bl1, sizeof(buf)));
378 {
379 TestAlarm alarm;
380 my_completion->wait_for_complete();
381 }
382 char buf2[128];
383 memset(buf2, 0xdd, sizeof(buf2));
384 bufferlist bl2;
385 bl2.append(buf2, sizeof(buf2));
386 AioCompletion *my_completion2 =
387 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
388 ASSERT_EQ(0, striper.aio_append("RoundTripAppendPP", my_completion2, bl2, sizeof(buf2)));
389 {
390 TestAlarm alarm;
391 my_completion2->wait_for_complete();
392 }
393 bufferlist bl3;
394 AioCompletion *my_completion3 =
395 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
396 ASSERT_EQ(0, striper.aio_read("RoundTripAppendPP", my_completion3, &bl3, 2 * sizeof(buf), 0));
397 {
398 TestAlarm alarm;
399 my_completion3->wait_for_complete();
400 }
401 ASSERT_EQ(sizeof(buf) + sizeof(buf2), (unsigned)my_completion3->get_return_value());
402 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
403 ASSERT_EQ(0, memcmp(bl3.c_str() + sizeof(buf), buf2, sizeof(buf2)));
404 test_data.wait();
405 my_completion->release();
406 my_completion2->release();
407 my_completion3->release();
408 }
409
410 TEST_F(StriperTest, Flush) {
411 AioTestData test_data;
412 rados_completion_t my_completion;
413 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
414 set_completion_complete,
415 &my_completion));
416 char buf[128];
417 memset(buf, 0xee, sizeof(buf));
418 ASSERT_EQ(0, rados_striper_aio_write(striper, "Flush", my_completion, buf, sizeof(buf), 0));
419 rados_striper_aio_flush(striper);
420 char buf2[128];
421 memset(buf2, 0, sizeof(buf2));
422 rados_completion_t my_completion2;
423 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
424 set_completion_complete,
425 &my_completion2));
426 ASSERT_EQ(0, rados_striper_aio_read(striper, "Flush", my_completion2, buf2, sizeof(buf2), 0));
427 {
428 TestAlarm alarm;
429 rados_aio_wait_for_complete(my_completion2);
430 }
431 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
432 test_data.wait();
433 rados_aio_release(my_completion);
434 rados_aio_release(my_completion2);
435 }
436
437 TEST_F(StriperTestPP, FlushPP) {
438 AioTestData test_data;
439 AioCompletion *my_completion =
440 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
441 char buf[128];
442 memset(buf, 0xee, sizeof(buf));
443 bufferlist bl1;
444 bl1.append(buf, sizeof(buf));
445 ASSERT_EQ(0, striper.aio_write("FlushPP", my_completion, bl1, sizeof(buf), 0));
446 striper.aio_flush();
447 bufferlist bl2;
448 AioCompletion *my_completion2 =
449 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
450 ASSERT_EQ(0, striper.aio_read("FlushPP", my_completion2, &bl2, sizeof(buf), 0));
451 {
452 TestAlarm alarm;
453 my_completion2->wait_for_complete();
454 }
455 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
456 test_data.wait();
457 my_completion->release();
458 my_completion2->release();
459 }
460
461 TEST_F(StriperTest, RoundTripWriteFull) {
462 AioTestData test_data;
463 rados_completion_t my_completion, my_completion2, my_completion3;
464 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
465 set_completion_complete,
466 &my_completion));
467 char buf[128];
468 memset(buf, 0xcc, sizeof(buf));
469 ASSERT_EQ(0, rados_striper_aio_write(striper, "RoundTripWriteFull", my_completion, buf, sizeof(buf), 0));
470 {
471 TestAlarm alarm;
472 rados_aio_wait_for_complete(my_completion);
473 }
474 char buf2[64];
475 memset(buf2, 0xdd, sizeof(buf2));
476 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
477 set_completion_complete,
478 &my_completion2));
479 ASSERT_EQ(0, rados_striper_aio_write_full(striper, "RoundTripWriteFull", my_completion2, buf2, sizeof(buf2)));
480 {
481 TestAlarm alarm;
482 rados_aio_wait_for_complete(my_completion2);
483 }
484 char buf3[sizeof(buf) + sizeof(buf2)];
485 memset(buf3, 0, sizeof(buf3));
486 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
487 set_completion_complete,
488 &my_completion3));
489 ASSERT_EQ(0, rados_striper_aio_read(striper, "RoundTripWriteFull", my_completion3, buf3, sizeof(buf3), 0));
490 {
491 TestAlarm alarm;
492 rados_aio_wait_for_complete(my_completion3);
493 }
494 ASSERT_EQ(sizeof(buf2), (unsigned)rados_aio_get_return_value(my_completion3));
495 ASSERT_EQ(0, memcmp(buf3, buf2, sizeof(buf2)));
496 test_data.wait();
497 rados_aio_release(my_completion);
498 rados_aio_release(my_completion2);
499 rados_aio_release(my_completion3);
500 }
501
502 TEST_F(StriperTestPP, RoundTripWriteFullPP) {
503 AioTestData test_data;
504 AioCompletion *my_completion =
505 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
506 char buf[128];
507 memset(buf, 0xcc, sizeof(buf));
508 bufferlist bl1;
509 bl1.append(buf, sizeof(buf));
510 ASSERT_EQ(0, striper.aio_write("RoundTripWriteFullPP", my_completion, bl1, sizeof(buf), 0));
511 {
512 TestAlarm alarm;
513 my_completion->wait_for_complete();
514 }
515 char buf2[64];
516 memset(buf2, 0xdd, sizeof(buf2));
517 bufferlist bl2;
518 bl2.append(buf2, sizeof(buf2));
519 AioCompletion *my_completion2 =
520 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
521 ASSERT_EQ(0, striper.aio_write_full("RoundTripWriteFullPP", my_completion2, bl2));
522 {
523 TestAlarm alarm;
524 my_completion2->wait_for_complete();
525 }
526 bufferlist bl3;
527 AioCompletion *my_completion3 =
528 librados::Rados::aio_create_completion(&test_data, set_completion_complete);
529 ASSERT_EQ(0, striper.aio_read("RoundTripWriteFullPP", my_completion3, &bl3, sizeof(buf), 0));
530 {
531 TestAlarm alarm;
532 my_completion3->wait_for_complete();
533 }
534 ASSERT_EQ(sizeof(buf2), (unsigned)my_completion3->get_return_value());
535 ASSERT_EQ(0, memcmp(bl3.c_str(), buf2, sizeof(buf2)));
536 test_data.wait();
537 my_completion->release();
538 my_completion2->release();
539 my_completion3->release();
540 }
541
542 TEST_F(StriperTest, RemoveTest) {
543 char buf[128];
544 char buf2[sizeof(buf)];
545 // create oabject
546 memset(buf, 0xaa, sizeof(buf));
547 ASSERT_EQ(0, rados_striper_write(striper, "RemoveTest", buf, sizeof(buf), 0));
548 // async remove it
549 AioTestData test_data;
550 rados_completion_t my_completion;
551 ASSERT_EQ(0, rados_aio_create_completion2(&test_data,
552 set_completion_complete,
553 &my_completion));
554 ASSERT_EQ(0, rados_striper_aio_remove(striper, "RemoveTest", my_completion));
555 {
556 TestAlarm alarm;
557 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
558 }
559 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
560 rados_aio_release(my_completion);
561 // check we get ENOENT on reading
562 ASSERT_EQ(-ENOENT, rados_striper_read(striper, "RemoveTest", buf2, sizeof(buf2), 0));
563 }
564
565 TEST_F(StriperTestPP, RemoveTestPP) {
566 char buf[128];
567 memset(buf, 0xaa, sizeof(buf));
568 bufferlist bl;
569 bl.append(buf, sizeof(buf));
570 ASSERT_EQ(0, striper.write("RemoveTestPP", bl, sizeof(buf), 0));
571 AioCompletion *my_completion = cluster.aio_create_completion(nullptr, nullptr);
572 ASSERT_EQ(0, striper.aio_remove("RemoveTestPP", my_completion));
573 {
574 TestAlarm alarm;
575 ASSERT_EQ(0, my_completion->wait_for_complete());
576 }
577 ASSERT_EQ(0, my_completion->get_return_value());
578 bufferlist bl2;
579 ASSERT_EQ(-ENOENT, striper.read("RemoveTestPP", &bl2, sizeof(buf), 0));
580 my_completion->release();
581 }