]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librados/aio.cc
ff5064ba353e1244b8112c07cef680ebcbe3af43
[ceph.git] / ceph / src / test / librados / aio.cc
1 #include "common/errno.h"
2 #include "include/err.h"
3 #include "include/rados/librados.h"
4 #include "test/librados/test.h"
5 #include "include/types.h"
6 #include "include/stringify.h"
7
8 #include "gtest/gtest.h"
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <semaphore.h>
12 #include <sstream>
13 #include <string>
14 #include <boost/scoped_ptr.hpp>
15 #include <utility>
16
17 using std::ostringstream;
18 using namespace librados;
19 using std::pair;
20
21 class AioTestData
22 {
23 public:
24 AioTestData()
25 : m_cluster(NULL),
26 m_ioctx(NULL),
27 m_init(false),
28 m_complete(false),
29 m_safe(false)
30 {
31 }
32
33 ~AioTestData()
34 {
35 if (m_init) {
36 rados_ioctx_destroy(m_ioctx);
37 destroy_one_pool(m_pool_name, &m_cluster);
38 sem_close(m_sem);
39 }
40 }
41
42 std::string init()
43 {
44 int ret;
45 if (SEM_FAILED == (m_sem = sem_open("/test_aio_sem", O_CREAT, 0644, 0))) {
46 int err = errno;
47 ostringstream oss;
48 oss << "sem_open failed: " << cpp_strerror(err);
49 return oss.str();
50 }
51 m_pool_name = get_temp_pool_name();
52 std::string err = create_one_pool(m_pool_name, &m_cluster);
53 if (!err.empty()) {
54 sem_close(m_sem);
55 ostringstream oss;
56 oss << "create_one_pool(" << m_pool_name << ") failed: error " << err;
57 return oss.str();
58 }
59 ret = rados_ioctx_create(m_cluster, m_pool_name.c_str(), &m_ioctx);
60 if (ret) {
61 sem_close(m_sem);
62 destroy_one_pool(m_pool_name, &m_cluster);
63 ostringstream oss;
64 oss << "rados_ioctx_create failed: error " << ret;
65 return oss.str();
66 }
67 m_init = true;
68 return "";
69 }
70
71 sem_t *m_sem;
72 rados_t m_cluster;
73 rados_ioctx_t m_ioctx;
74 std::string m_pool_name;
75 bool m_init;
76 bool m_complete;
77 bool m_safe;
78 };
79
80 class AioTestDataPP
81 {
82 public:
83 AioTestDataPP()
84 : m_init(false),
85 m_complete(false),
86 m_safe(false)
87 {
88 }
89
90 ~AioTestDataPP()
91 {
92 if (m_init) {
93 m_ioctx.close();
94 destroy_one_pool_pp(m_pool_name, m_cluster);
95 sem_close(m_sem);
96 }
97 }
98
99 std::string init()
100 {
101 return init({});
102 }
103
104 std::string init(const std::map<std::string, std::string> &config)
105 {
106 int ret;
107
108 if (SEM_FAILED == (m_sem = sem_open("/test_aio_sem", O_CREAT, 0644, 0))) {
109 int err = errno;
110 ostringstream oss;
111 oss << "sem_open failed: " << cpp_strerror(err);
112 return oss.str();
113 }
114 m_pool_name = get_temp_pool_name();
115 std::string err = create_one_pool_pp(m_pool_name, m_cluster, config);
116 if (!err.empty()) {
117 sem_close(m_sem);
118 ostringstream oss;
119 oss << "create_one_pool(" << m_pool_name << ") failed: error " << err;
120 return oss.str();
121 }
122 ret = m_cluster.ioctx_create(m_pool_name.c_str(), m_ioctx);
123 if (ret) {
124 sem_close(m_sem);
125 destroy_one_pool_pp(m_pool_name, m_cluster);
126 ostringstream oss;
127 oss << "rados_ioctx_create failed: error " << ret;
128 return oss.str();
129 }
130 m_init = true;
131 return "";
132 }
133
134 sem_t *m_sem;
135 Rados m_cluster;
136 IoCtx m_ioctx;
137 std::string m_pool_name;
138 bool m_init;
139 bool m_complete;
140 bool m_safe;
141 };
142
143 void set_completion_complete(rados_completion_t cb, void *arg)
144 {
145 AioTestData *test = static_cast<AioTestData*>(arg);
146 test->m_complete = true;
147 sem_post(test->m_sem);
148 }
149
150 void set_completion_safe(rados_completion_t cb, void *arg)
151 {
152 AioTestData *test = static_cast<AioTestData*>(arg);
153 test->m_safe = true;
154 sem_post(test->m_sem);
155 }
156
157 void set_completion_completePP(rados_completion_t cb, void *arg)
158 {
159 AioTestDataPP *test = static_cast<AioTestDataPP*>(arg);
160 test->m_complete = true;
161 sem_post(test->m_sem);
162 }
163
164 void set_completion_safePP(rados_completion_t cb, void *arg)
165 {
166 AioTestDataPP *test = static_cast<AioTestDataPP*>(arg);
167 test->m_safe = true;
168 sem_post(test->m_sem);
169 }
170
171 TEST(LibRadosAio, TooBig) {
172 AioTestData test_data;
173 rados_completion_t my_completion;
174 ASSERT_EQ("", test_data.init());
175 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
176 set_completion_complete, set_completion_safe, &my_completion));
177 char buf[128];
178 memset(buf, 0xcc, sizeof(buf));
179 ASSERT_EQ(-E2BIG, rados_aio_write(test_data.m_ioctx, "foo",
180 my_completion, buf, UINT_MAX, 0));
181 ASSERT_EQ(-E2BIG, rados_aio_write_full(test_data.m_ioctx, "foo",
182 my_completion, buf, UINT_MAX));
183 ASSERT_EQ(-E2BIG, rados_aio_append(test_data.m_ioctx, "foo",
184 my_completion, buf, UINT_MAX));
185 rados_aio_release(my_completion);
186 }
187
188 TEST(LibRadosAio, TooBigPP) {
189 AioTestDataPP test_data;
190 ASSERT_EQ("", test_data.init());
191
192 bufferlist bl;
193 AioCompletion *aio_completion = test_data.m_cluster.aio_create_completion(
194 (void*)&test_data, NULL, NULL);
195 ASSERT_EQ(-E2BIG, test_data.m_ioctx.aio_write("foo", aio_completion, bl, UINT_MAX, 0));
196 ASSERT_EQ(-E2BIG, test_data.m_ioctx.aio_append("foo", aio_completion, bl, UINT_MAX));
197 // ioctx.aio_write_full no way to overflow bl.length()
198 delete aio_completion;
199 }
200
201 TEST(LibRadosAio, PoolQuotaPP) {
202 AioTestDataPP test_data;
203 ASSERT_EQ("", test_data.init());
204 string p = get_temp_pool_name();
205 ASSERT_EQ(0, test_data.m_cluster.pool_create(p.c_str()));
206 IoCtx ioctx;
207 ASSERT_EQ(0, test_data.m_cluster.ioctx_create(p.c_str(), ioctx));
208 ioctx.application_enable("rados", true);
209
210 bufferlist inbl;
211 ASSERT_EQ(0, test_data.m_cluster.mon_command(
212 "{\"prefix\": \"osd pool set-quota\", \"pool\": \"" + p +
213 "\", \"field\": \"max_bytes\", \"val\": \"4096\"}",
214 inbl, NULL, NULL));
215
216 bufferlist bl;
217 bufferptr z(4096);
218 bl.append(z);
219 int n;
220 for (n = 0; n < 1024; ++n) {
221 ObjectWriteOperation op;
222 op.write_full(bl);
223 librados::AioCompletion *completion =
224 test_data.m_cluster.aio_create_completion();
225 ASSERT_EQ(0, ioctx.aio_operate(
226 "foo" + stringify(n), completion, &op,
227 librados::OPERATION_FULL_TRY));
228 completion->wait_for_safe();
229 int r = completion->get_return_value();
230 completion->release();
231 if (r == -EDQUOT)
232 break;
233 ASSERT_EQ(0, r);
234 sleep(1);
235 }
236 ASSERT_LT(n, 1024);
237
238 // make sure we block without FULL_TRY
239 {
240 ObjectWriteOperation op;
241 op.write_full(bl);
242 librados::AioCompletion *completion =
243 test_data.m_cluster.aio_create_completion();
244 ASSERT_EQ(0, ioctx.aio_operate("bar", completion, &op, 0));
245 sleep(5);
246 ASSERT_FALSE(completion->is_safe());
247 completion->release();
248 }
249
250 ioctx.close();
251 ASSERT_EQ(0, test_data.m_cluster.pool_delete(p.c_str()));
252 }
253
254 TEST(LibRadosAio, SimpleWrite) {
255 AioTestData test_data;
256 rados_completion_t my_completion;
257 ASSERT_EQ("", test_data.init());
258 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
259 set_completion_complete, set_completion_safe, &my_completion));
260 char buf[128];
261 memset(buf, 0xcc, sizeof(buf));
262 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
263 my_completion, buf, sizeof(buf), 0));
264 {
265 TestAlarm alarm;
266 sem_wait(test_data.m_sem);
267 sem_wait(test_data.m_sem);
268 }
269 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
270
271 rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
272 rados_completion_t my_completion2;
273 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
274 set_completion_complete, set_completion_safe, &my_completion2));
275 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
276 my_completion2, buf, sizeof(buf), 0));
277 {
278 TestAlarm alarm;
279 sem_wait(test_data.m_sem);
280 sem_wait(test_data.m_sem);
281 }
282 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
283 rados_aio_release(my_completion);
284 rados_aio_release(my_completion2);
285 }
286
287 TEST(LibRadosAio, SimpleWritePP) {
288 char buf[128];
289 memset(buf, 0xcc, sizeof(buf));
290 bufferlist bl1;
291 bl1.append(buf, sizeof(buf));
292 {
293 AioTestDataPP test_data;
294 ASSERT_EQ("", test_data.init());
295 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
296 (void*)&test_data, set_completion_completePP, set_completion_safePP);
297 AioCompletion *my_completion_null = NULL;
298 ASSERT_NE(my_completion, my_completion_null);
299 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
300 my_completion, bl1, sizeof(buf), 0));
301 {
302 TestAlarm alarm;
303 sem_wait(test_data.m_sem);
304 sem_wait(test_data.m_sem);
305 }
306 ASSERT_EQ(0, my_completion->get_return_value());
307 delete my_completion;
308 }
309
310 {
311 AioTestDataPP test_data;
312 ASSERT_EQ("", test_data.init());
313 test_data.m_ioctx.set_namespace("nspace");
314 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
315 (void*)&test_data, set_completion_completePP, set_completion_safePP);
316 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
317 my_completion, bl1, sizeof(buf), 0));
318 {
319 TestAlarm alarm;
320 sem_wait(test_data.m_sem);
321 sem_wait(test_data.m_sem);
322 }
323 ASSERT_EQ(0, my_completion->get_return_value());
324 delete my_completion;
325 }
326 }
327
328 TEST(LibRadosAio, WaitForSafe) {
329 AioTestData test_data;
330 rados_completion_t my_completion;
331 ASSERT_EQ("", test_data.init());
332 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
333 set_completion_complete, set_completion_safe, &my_completion));
334 char buf[128];
335 memset(buf, 0xcc, sizeof(buf));
336 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
337 my_completion, buf, sizeof(buf), 0));
338 TestAlarm alarm;
339 ASSERT_EQ(0, rados_aio_wait_for_safe(my_completion));
340 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
341 rados_aio_release(my_completion);
342 }
343
344 TEST(LibRadosAio, WaitForSafePP) {
345 AioTestDataPP test_data;
346 ASSERT_EQ("", test_data.init());
347 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
348 (void*)&test_data, set_completion_completePP, set_completion_safePP);
349 AioCompletion *my_completion_null = NULL;
350 ASSERT_NE(my_completion, my_completion_null);
351 char buf[128];
352 memset(buf, 0xcc, sizeof(buf));
353 bufferlist bl1;
354 bl1.append(buf, sizeof(buf));
355 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
356 my_completion, bl1, sizeof(buf), 0));
357 TestAlarm alarm;
358 ASSERT_EQ(0, my_completion->wait_for_safe());
359 ASSERT_EQ(0, my_completion->get_return_value());
360 delete my_completion;
361 }
362
363 TEST(LibRadosAio, RoundTrip) {
364 AioTestData test_data;
365 rados_completion_t my_completion;
366 ASSERT_EQ("", test_data.init());
367 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
368 set_completion_complete, set_completion_safe, &my_completion));
369 char buf[128];
370 memset(buf, 0xcc, sizeof(buf));
371 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
372 my_completion, buf, sizeof(buf), 0));
373 {
374 TestAlarm alarm;
375 sem_wait(test_data.m_sem);
376 sem_wait(test_data.m_sem);
377 }
378 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
379 char buf2[256];
380 memset(buf2, 0, sizeof(buf2));
381 rados_completion_t my_completion2;
382 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
383 set_completion_complete, set_completion_safe, &my_completion2));
384 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
385 my_completion2, buf2, sizeof(buf2), 0));
386 {
387 TestAlarm alarm;
388 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
389 }
390 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
391 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
392 rados_aio_release(my_completion);
393 rados_aio_release(my_completion2);
394 }
395
396 TEST(LibRadosAio, RoundTrip2) {
397 AioTestData test_data;
398 rados_completion_t my_completion;
399 ASSERT_EQ("", test_data.init());
400 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
401 set_completion_complete, set_completion_safe, &my_completion));
402 char buf[128];
403 memset(buf, 0xcc, sizeof(buf));
404 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
405 my_completion, buf, sizeof(buf), 0));
406 {
407 TestAlarm alarm;
408 sem_wait(test_data.m_sem);
409 sem_wait(test_data.m_sem);
410 }
411 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
412 char buf2[128];
413 memset(buf2, 0, sizeof(buf2));
414 rados_completion_t my_completion2;
415 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
416 set_completion_complete, set_completion_safe, &my_completion2));
417 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
418 my_completion2, buf2, sizeof(buf2), 0));
419 {
420 TestAlarm alarm;
421 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
422 }
423 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
424 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
425 rados_aio_release(my_completion);
426 rados_aio_release(my_completion2);
427 }
428
429 TEST(LibRadosAio, RoundTrip3) {
430 AioTestData test_data;
431 rados_completion_t my_completion;
432 ASSERT_EQ("", test_data.init());
433 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
434 set_completion_complete, set_completion_safe, &my_completion));
435 char buf[128];
436 memset(buf, 0xcc, sizeof(buf));
437
438 rados_write_op_t op1 = rados_create_write_op();
439 rados_write_op_write(op1, buf, sizeof(buf), 0);
440 rados_write_op_set_alloc_hint2(op1, 0, 0, LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
441 ASSERT_EQ(0, rados_aio_write_op_operate(op1, test_data.m_ioctx, my_completion,
442 "foo", NULL, 0));
443 rados_release_write_op(op1);
444
445 {
446 TestAlarm alarm;
447 sem_wait(test_data.m_sem);
448 sem_wait(test_data.m_sem);
449 }
450
451 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
452 rados_aio_release(my_completion);
453
454 char buf2[128];
455 memset(buf2, 0, sizeof(buf2));
456 rados_completion_t my_completion2;
457 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
458 set_completion_complete, set_completion_safe, &my_completion2));
459
460 rados_read_op_t op2 = rados_create_read_op();
461 rados_read_op_read(op2, 0, sizeof(buf2), buf2, NULL, NULL);
462 rados_read_op_set_flags(op2, LIBRADOS_OP_FLAG_FADVISE_NOCACHE |
463 LIBRADOS_OP_FLAG_FADVISE_RANDOM);
464 __le32 init_value = -1;
465 __le32 checksum[2];
466 rados_read_op_checksum(op2, LIBRADOS_CHECKSUM_TYPE_CRC32C,
467 reinterpret_cast<char *>(&init_value),
468 sizeof(init_value), 0, 0, 0,
469 reinterpret_cast<char *>(&checksum),
470 sizeof(checksum), NULL);
471 ASSERT_EQ(0, rados_aio_read_op_operate(op2, test_data.m_ioctx, my_completion2,
472 "foo", 0));
473 rados_release_read_op(op2);
474
475 {
476 TestAlarm alarm;
477 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
478 }
479 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
480 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
481 rados_aio_release(my_completion2);
482
483 bufferlist bl;
484 bl.append(buf, sizeof(buf));
485 ASSERT_EQ(1U, checksum[0]);
486 ASSERT_EQ(bl.crc32c(-1), checksum[1]);
487 }
488
489 TEST(LibRadosAio, RoundTripPP) {
490 AioTestDataPP test_data;
491 ASSERT_EQ("", test_data.init());
492 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
493 (void*)&test_data, set_completion_completePP, set_completion_safePP);
494 AioCompletion *my_completion_null = NULL;
495 ASSERT_NE(my_completion, my_completion_null);
496 char buf[128];
497 memset(buf, 0xcc, sizeof(buf));
498 bufferlist bl1;
499 bl1.append(buf, sizeof(buf));
500 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
501 bl1, sizeof(buf), 0));
502 {
503 TestAlarm alarm;
504 sem_wait(test_data.m_sem);
505 sem_wait(test_data.m_sem);
506 }
507 ASSERT_EQ(0, my_completion->get_return_value());
508 bufferlist bl2;
509 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
510 (void*)&test_data, set_completion_completePP, set_completion_safePP);
511 ASSERT_NE(my_completion2, my_completion_null);
512 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo",
513 my_completion2, &bl2, sizeof(buf), 0));
514 {
515 TestAlarm alarm;
516 ASSERT_EQ(0, my_completion2->wait_for_complete());
517 }
518 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
519 ASSERT_EQ(sizeof(buf), bl2.length());
520 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
521 delete my_completion;
522 delete my_completion2;
523 }
524
525 TEST(LibRadosAio, RoundTripPP2) {
526 AioTestDataPP test_data;
527 ASSERT_EQ("", test_data.init());
528 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
529 (void*)&test_data, set_completion_completePP, set_completion_safePP);
530 AioCompletion *my_completion_null = NULL;
531 ASSERT_NE(my_completion, my_completion_null);
532 char buf[128];
533 memset(buf, 0xcc, sizeof(buf));
534 bufferlist bl1;
535 bl1.append(buf, sizeof(buf));
536 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
537 bl1, sizeof(buf), 0));
538 {
539 TestAlarm alarm;
540 sem_wait(test_data.m_sem);
541 sem_wait(test_data.m_sem);
542 }
543 ASSERT_EQ(0, my_completion->get_return_value());
544 bufferlist bl2;
545 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
546 (void*)&test_data, set_completion_completePP, set_completion_safePP);
547 ASSERT_NE(my_completion2, my_completion_null);
548 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo",
549 my_completion2, &bl2, sizeof(buf), 0));
550 {
551 TestAlarm alarm;
552 ASSERT_EQ(0, my_completion2->wait_for_safe());
553 ASSERT_EQ(0, my_completion2->wait_for_complete());
554 }
555 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
556 ASSERT_EQ(sizeof(buf), bl2.length());
557 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
558 delete my_completion;
559 delete my_completion2;
560 }
561
562 //using ObjectWriteOperation/ObjectReadOperation with iohint
563 TEST(LibRadosAio, RoundTripPP3)
564 {
565 Rados cluster;
566 std::string pool_name = get_temp_pool_name();
567 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
568 IoCtx ioctx;
569 cluster.ioctx_create(pool_name.c_str(), ioctx);
570
571 boost::scoped_ptr<AioCompletion> my_completion1(cluster.aio_create_completion(0, 0, 0));
572 ObjectWriteOperation op;
573 char buf[128];
574 memset(buf, 0xcc, sizeof(buf));
575 bufferlist bl;
576 bl.append(buf, sizeof(buf));
577
578 op.write(0, bl);
579 op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
580 ioctx.aio_operate("test_obj", my_completion1.get(), &op);
581 {
582 TestAlarm alarm;
583 ASSERT_EQ(0, my_completion1->wait_for_complete());
584 }
585 EXPECT_EQ(0, my_completion1->get_return_value());
586
587 boost::scoped_ptr<AioCompletion> my_completion2(cluster.aio_create_completion(0, 0, 0));
588 bl.clear();
589 ObjectReadOperation op1;
590 op1.read(0, sizeof(buf), &bl, NULL);
591 op1.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED|LIBRADOS_OP_FLAG_FADVISE_RANDOM);
592 bufferlist init_value_bl;
593 ::encode(static_cast<int32_t>(-1), init_value_bl);
594 bufferlist csum_bl;
595 op1.checksum(LIBRADOS_CHECKSUM_TYPE_CRC32C, init_value_bl,
596 0, 0, 0, &csum_bl, nullptr);
597 ioctx.aio_operate("test_obj", my_completion2.get(), &op1, 0);
598 {
599 TestAlarm alarm;
600 ASSERT_EQ(0, my_completion2->wait_for_complete());
601 }
602 EXPECT_EQ(0, my_completion2->get_return_value());
603 ASSERT_EQ(0, memcmp(buf, bl.c_str(), sizeof(buf)));
604
605 ASSERT_EQ(8U, csum_bl.length());
606 auto csum_bl_it = csum_bl.begin();
607 uint32_t csum_count;
608 uint32_t csum;
609 ::decode(csum_count, csum_bl_it);
610 ASSERT_EQ(1U, csum_count);
611 ::decode(csum, csum_bl_it);
612 ASSERT_EQ(bl.crc32c(-1), csum);
613 ioctx.remove("test_obj");
614 destroy_one_pool_pp(pool_name, cluster);
615 }
616
617 TEST(LibRadosAio, RoundTripSparseReadPP) {
618 AioTestDataPP test_data;
619 ASSERT_EQ("", test_data.init());
620 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
621 (void*)&test_data, set_completion_completePP, set_completion_safePP);
622 AioCompletion *my_completion_null = NULL;
623 ASSERT_NE(my_completion, my_completion_null);
624 char buf[128];
625 memset(buf, 0xcc, sizeof(buf));
626 bufferlist bl1;
627 bl1.append(buf, sizeof(buf));
628 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
629 bl1, sizeof(buf), 0));
630 {
631 TestAlarm alarm;
632 sem_wait(test_data.m_sem);
633 sem_wait(test_data.m_sem);
634 }
635 ASSERT_EQ(0, my_completion->get_return_value());
636 std::map<uint64_t, uint64_t> extents;
637 bufferlist bl2;
638 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
639 (void*)&test_data, set_completion_completePP, set_completion_safePP);
640 ASSERT_NE(my_completion2, my_completion_null);
641 ASSERT_EQ(0, test_data.m_ioctx.aio_sparse_read("foo",
642 my_completion2, &extents, &bl2, sizeof(buf), 0));
643 {
644 TestAlarm alarm;
645 ASSERT_EQ(0, my_completion2->wait_for_complete());
646 }
647 ASSERT_EQ(0, my_completion2->get_return_value());
648 assert_eq_sparse(bl1, extents, bl2);
649 delete my_completion;
650 delete my_completion2;
651 }
652
653 TEST(LibRadosAio, RoundTripAppend) {
654 AioTestData test_data;
655 rados_completion_t my_completion, my_completion2, my_completion3;
656 ASSERT_EQ("", test_data.init());
657 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
658 set_completion_complete, set_completion_safe, &my_completion));
659 char buf[128];
660 memset(buf, 0xcc, sizeof(buf));
661 ASSERT_EQ(0, rados_aio_append(test_data.m_ioctx, "foo",
662 my_completion, buf, sizeof(buf)));
663 {
664 TestAlarm alarm;
665 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
666 }
667 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
668 char buf2[128];
669 memset(buf2, 0xdd, sizeof(buf2));
670 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
671 set_completion_complete, set_completion_safe, &my_completion2));
672 ASSERT_EQ(0, rados_aio_append(test_data.m_ioctx, "foo",
673 my_completion2, buf2, sizeof(buf2)));
674 {
675 TestAlarm alarm;
676 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
677 }
678 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
679 char buf3[sizeof(buf) + sizeof(buf2)];
680 memset(buf3, 0, sizeof(buf3));
681 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
682 set_completion_complete, set_completion_safe, &my_completion3));
683 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
684 my_completion3, buf3, sizeof(buf3), 0));
685 {
686 TestAlarm alarm;
687 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
688 }
689 ASSERT_EQ((int)sizeof(buf3), rados_aio_get_return_value(my_completion3));
690 ASSERT_EQ(0, memcmp(buf3, buf, sizeof(buf)));
691 ASSERT_EQ(0, memcmp(buf3 + sizeof(buf), buf2, sizeof(buf2)));
692 rados_aio_release(my_completion);
693 rados_aio_release(my_completion2);
694 rados_aio_release(my_completion3);
695 }
696
697 TEST(LibRadosAio, RoundTripAppendPP) {
698 AioTestDataPP test_data;
699 ASSERT_EQ("", test_data.init());
700 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
701 (void*)&test_data, set_completion_complete, set_completion_safe);
702 AioCompletion *my_completion_null = NULL;
703 ASSERT_NE(my_completion, my_completion_null);
704 char buf[128];
705 memset(buf, 0xcc, sizeof(buf));
706 bufferlist bl1;
707 bl1.append(buf, sizeof(buf));
708 ASSERT_EQ(0, test_data.m_ioctx.aio_append("foo", my_completion,
709 bl1, sizeof(buf)));
710 {
711 TestAlarm alarm;
712 ASSERT_EQ(0, my_completion->wait_for_complete());
713 }
714 ASSERT_EQ(0, my_completion->get_return_value());
715 char buf2[128];
716 memset(buf2, 0xdd, sizeof(buf2));
717 bufferlist bl2;
718 bl2.append(buf2, sizeof(buf2));
719 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
720 (void*)&test_data, set_completion_complete, set_completion_safe);
721 ASSERT_NE(my_completion2, my_completion_null);
722 ASSERT_EQ(0, test_data.m_ioctx.aio_append("foo", my_completion2,
723 bl2, sizeof(buf2)));
724 {
725 TestAlarm alarm;
726 ASSERT_EQ(0, my_completion2->wait_for_complete());
727 }
728 ASSERT_EQ(0, my_completion2->get_return_value());
729 bufferlist bl3;
730 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
731 (void*)&test_data, set_completion_complete, set_completion_safe);
732 ASSERT_NE(my_completion3, my_completion_null);
733 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo",
734 my_completion3, &bl3, 2 * sizeof(buf), 0));
735 {
736 TestAlarm alarm;
737 ASSERT_EQ(0, my_completion3->wait_for_complete());
738 }
739 ASSERT_EQ((int)(sizeof(buf) * 2), my_completion3->get_return_value());
740 ASSERT_EQ(sizeof(buf) * 2, bl3.length());
741 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
742 ASSERT_EQ(0, memcmp(bl3.c_str() + sizeof(buf), buf2, sizeof(buf2)));
743 delete my_completion;
744 delete my_completion2;
745 delete my_completion3;
746 }
747
748 TEST(LibRadosAio, RemoveTest) {
749 char buf[128];
750 char buf2[sizeof(buf)];
751 rados_completion_t my_completion;
752 AioTestData test_data;
753 ASSERT_EQ("", test_data.init());
754 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
755 set_completion_complete, set_completion_safe, &my_completion));
756 memset(buf, 0xaa, sizeof(buf));
757 ASSERT_EQ(0, rados_append(test_data.m_ioctx, "foo", buf, sizeof(buf)));
758 ASSERT_EQ(0, rados_aio_remove(test_data.m_ioctx, "foo", my_completion));
759 {
760 TestAlarm alarm;
761 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
762 }
763 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
764 memset(buf2, 0, sizeof(buf2));
765 ASSERT_EQ(-ENOENT, rados_read(test_data.m_ioctx, "foo", buf2, sizeof(buf2), 0));
766 rados_aio_release(my_completion);
767 }
768
769 TEST(LibRadosAioPP, RemoveTestPP) {
770 char buf[128];
771 memset(buf, 0xaa, sizeof(buf));
772 bufferlist bl1;
773 bl1.append(buf, sizeof(buf));
774 AioTestDataPP test_data;
775 ASSERT_EQ("", test_data.init());
776 ASSERT_EQ(0, test_data.m_ioctx.append("foo", bl1, sizeof(buf)));
777 boost::scoped_ptr<AioCompletion> my_completion
778 (test_data.m_cluster.aio_create_completion
779 ((void*)&test_data, set_completion_completePP, set_completion_safePP));
780 ASSERT_EQ(0, test_data.m_ioctx.aio_remove("foo", my_completion.get()));
781 {
782 TestAlarm alarm;
783 ASSERT_EQ(0, my_completion->wait_for_complete());
784 }
785 ASSERT_EQ(0, my_completion->get_return_value());
786 bufferlist bl2;
787 ASSERT_EQ(-ENOENT, test_data.m_ioctx.read("foo", bl2, sizeof(buf), 0));
788 }
789
790 TEST(LibRadosAio, XattrsRoundTrip) {
791 char buf[128];
792 char attr1[] = "attr1";
793 char attr1_buf[] = "foo bar baz";
794 // append
795 AioTestData test_data;
796 ASSERT_EQ("", test_data.init());
797 memset(buf, 0xaa, sizeof(buf));
798 ASSERT_EQ(0, rados_append(test_data.m_ioctx, "foo", buf, sizeof(buf)));
799 // async getxattr
800 rados_completion_t my_completion;
801 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
802 set_completion_complete, set_completion_safe, &my_completion));
803 ASSERT_EQ(0, rados_aio_getxattr(test_data.m_ioctx, "foo", my_completion, attr1, buf, sizeof(buf)));
804 {
805 TestAlarm alarm;
806 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
807 }
808 ASSERT_EQ(-ENODATA, rados_aio_get_return_value(my_completion));
809 rados_aio_release(my_completion);
810 // async setxattr
811 rados_completion_t my_completion2;
812 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
813 set_completion_complete, set_completion_safe, &my_completion2));
814 ASSERT_EQ(0, rados_aio_setxattr(test_data.m_ioctx, "foo", my_completion2, attr1, attr1_buf, sizeof(attr1_buf)));
815 {
816 TestAlarm alarm;
817 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
818 }
819 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
820 rados_aio_release(my_completion2);
821 // async getxattr
822 rados_completion_t my_completion3;
823 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
824 set_completion_complete, set_completion_safe, &my_completion3));
825 ASSERT_EQ(0, rados_aio_getxattr(test_data.m_ioctx, "foo", my_completion3, attr1, buf, sizeof(buf)));
826 {
827 TestAlarm alarm;
828 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
829 }
830 ASSERT_EQ((int)sizeof(attr1_buf), rados_aio_get_return_value(my_completion3));
831 rados_aio_release(my_completion3);
832 // check content of attribute
833 ASSERT_EQ(0, memcmp(attr1_buf, buf, sizeof(attr1_buf)));
834 }
835
836 TEST(LibRadosAioPP, XattrsRoundTripPP) {
837 char buf[128];
838 char attr1[] = "attr1";
839 char attr1_buf[] = "foo bar baz";
840 memset(buf, 0xaa, sizeof(buf));
841 bufferlist bl1;
842 bl1.append(buf, sizeof(buf));
843 AioTestDataPP test_data;
844 ASSERT_EQ("", test_data.init());
845 ASSERT_EQ(0, test_data.m_ioctx.append("foo", bl1, sizeof(buf)));
846 bufferlist bl2;
847 // async getxattr
848 boost::scoped_ptr<AioCompletion> my_completion
849 (test_data.m_cluster.aio_create_completion
850 ((void*)&test_data, set_completion_completePP, set_completion_safePP));
851 ASSERT_EQ(0, test_data.m_ioctx.aio_getxattr("foo", my_completion.get(), attr1, bl2));
852 {
853 TestAlarm alarm;
854 ASSERT_EQ(0, my_completion->wait_for_complete());
855 }
856 ASSERT_EQ(-ENODATA, my_completion->get_return_value());
857 // append
858 bufferlist bl3;
859 bl3.append(attr1_buf, sizeof(attr1_buf));
860 // async setxattr
861 AioTestDataPP test_data2;
862 ASSERT_EQ("", test_data2.init());
863 boost::scoped_ptr<AioCompletion> my_completion2
864 (test_data.m_cluster.aio_create_completion
865 ((void*)&test_data2, set_completion_completePP, set_completion_safePP));
866 ASSERT_EQ(0, test_data.m_ioctx.aio_setxattr("foo", my_completion2.get(), attr1, bl3));
867 {
868 TestAlarm alarm;
869 ASSERT_EQ(0, my_completion2->wait_for_complete());
870 }
871 ASSERT_EQ(0, my_completion2->get_return_value());
872 // async getxattr
873 bufferlist bl4;
874 AioTestDataPP test_data3;
875 ASSERT_EQ("", test_data3.init());
876 boost::scoped_ptr<AioCompletion> my_completion3
877 (test_data.m_cluster.aio_create_completion
878 ((void*)&test_data3, set_completion_completePP, set_completion_safePP));
879 ASSERT_EQ(0, test_data.m_ioctx.aio_getxattr("foo", my_completion3.get(), attr1, bl4));
880 {
881 TestAlarm alarm;
882 ASSERT_EQ(0, my_completion3->wait_for_complete());
883 }
884 ASSERT_EQ((int)sizeof(attr1_buf), my_completion3->get_return_value());
885 // check content of attribute
886 ASSERT_EQ(0, memcmp(bl4.c_str(), attr1_buf, sizeof(attr1_buf)));
887 }
888
889 TEST(LibRadosAio, RmXattr) {
890 char buf[128];
891 char attr1[] = "attr1";
892 char attr1_buf[] = "foo bar baz";
893 // append
894 memset(buf, 0xaa, sizeof(buf));
895 AioTestData test_data;
896 ASSERT_EQ("", test_data.init());
897 ASSERT_EQ(0, rados_append(test_data.m_ioctx, "foo", buf, sizeof(buf)));
898 // async setxattr
899 rados_completion_t my_completion;
900 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
901 set_completion_complete, set_completion_safe, &my_completion));
902 ASSERT_EQ(0, rados_aio_setxattr(test_data.m_ioctx, "foo", my_completion, attr1, attr1_buf, sizeof(attr1_buf)));
903 {
904 TestAlarm alarm;
905 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
906 }
907 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
908 rados_aio_release(my_completion);
909 // async rmxattr
910 rados_completion_t my_completion2;
911 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
912 set_completion_complete, set_completion_safe, &my_completion2));
913 ASSERT_EQ(0, rados_aio_rmxattr(test_data.m_ioctx, "foo", my_completion2, attr1));
914 {
915 TestAlarm alarm;
916 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
917 }
918 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
919 rados_aio_release(my_completion2);
920 // async getxattr after deletion
921 rados_completion_t my_completion3;
922 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
923 set_completion_complete, set_completion_safe, &my_completion3));
924 ASSERT_EQ(0, rados_aio_getxattr(test_data.m_ioctx, "foo", my_completion3, attr1, buf, sizeof(buf)));
925 {
926 TestAlarm alarm;
927 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
928 }
929 ASSERT_EQ(-ENODATA, rados_aio_get_return_value(my_completion3));
930 rados_aio_release(my_completion3);
931 // Test rmxattr on a removed object
932 char buf2[128];
933 char attr2[] = "attr2";
934 char attr2_buf[] = "foo bar baz";
935 memset(buf2, 0xbb, sizeof(buf2));
936 ASSERT_EQ(0, rados_write(test_data.m_ioctx, "foo_rmxattr", buf2, sizeof(buf2), 0));
937 // asynx setxattr
938 rados_completion_t my_completion4;
939 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
940 set_completion_complete, set_completion_safe, &my_completion4));
941 ASSERT_EQ(0, rados_aio_setxattr(test_data.m_ioctx, "foo_rmxattr", my_completion4, attr2, attr2_buf, sizeof(attr2_buf)));
942 {
943 TestAlarm alarm;
944 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4));
945 }
946 ASSERT_EQ(0, rados_aio_get_return_value(my_completion4));
947 rados_aio_release(my_completion4);
948 // remove object
949 ASSERT_EQ(0, rados_remove(test_data.m_ioctx, "foo_rmxattr"));
950 // async rmxattr on non existing object
951 rados_completion_t my_completion5;
952 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
953 set_completion_complete, set_completion_safe, &my_completion5));
954 ASSERT_EQ(0, rados_aio_rmxattr(test_data.m_ioctx, "foo_rmxattr", my_completion5, attr2));
955 {
956 TestAlarm alarm;
957 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion5));
958 }
959 ASSERT_EQ(-ENOENT, rados_aio_get_return_value(my_completion5));
960 rados_aio_release(my_completion5);
961 }
962
963 TEST(LibRadosAioPP, RmXattrPP) {
964 char buf[128];
965 char attr1[] = "attr1";
966 char attr1_buf[] = "foo bar baz";
967 memset(buf, 0xaa, sizeof(buf));
968 bufferlist bl1;
969 bl1.append(buf, sizeof(buf));
970 AioTestDataPP test_data;
971 ASSERT_EQ("", test_data.init());
972 ASSERT_EQ(0, test_data.m_ioctx.append("foo", bl1, sizeof(buf)));
973 // async setxattr
974 bufferlist bl2;
975 bl2.append(attr1_buf, sizeof(attr1_buf));
976 boost::scoped_ptr<AioCompletion> my_completion
977 (test_data.m_cluster.aio_create_completion
978 ((void*)&test_data, set_completion_completePP, set_completion_safePP));
979 ASSERT_EQ(0, test_data.m_ioctx.aio_setxattr("foo", my_completion.get(), attr1, bl2));
980 {
981 TestAlarm alarm;
982 ASSERT_EQ(0, my_completion->wait_for_complete());
983 }
984 ASSERT_EQ(0, my_completion->get_return_value());
985 // async rmxattr
986 AioTestDataPP test_data2;
987 ASSERT_EQ("", test_data2.init());
988 boost::scoped_ptr<AioCompletion> my_completion2
989 (test_data.m_cluster.aio_create_completion
990 ((void*)&test_data2, set_completion_completePP, set_completion_safePP));
991 ASSERT_EQ(0, test_data.m_ioctx.aio_rmxattr("foo", my_completion2.get(), attr1));
992 {
993 TestAlarm alarm;
994 ASSERT_EQ(0, my_completion2->wait_for_complete());
995 }
996 ASSERT_EQ(0, my_completion2->get_return_value());
997 // async getxattr
998 AioTestDataPP test_data3;
999 ASSERT_EQ("", test_data3.init());
1000 boost::scoped_ptr<AioCompletion> my_completion3
1001 (test_data.m_cluster.aio_create_completion
1002 ((void*)&test_data3, set_completion_completePP, set_completion_safePP));
1003 bufferlist bl3;
1004 ASSERT_EQ(0, test_data.m_ioctx.aio_getxattr("foo", my_completion3.get(), attr1, bl3));
1005 {
1006 TestAlarm alarm;
1007 ASSERT_EQ(0, my_completion3->wait_for_complete());
1008 }
1009 ASSERT_EQ(-ENODATA, my_completion3->get_return_value());
1010 // Test rmxattr on a removed object
1011 char buf2[128];
1012 char attr2[] = "attr2";
1013 char attr2_buf[] = "foo bar baz";
1014 memset(buf2, 0xbb, sizeof(buf2));
1015 bufferlist bl21;
1016 bl21.append(buf, sizeof(buf));
1017 ASSERT_EQ(0, test_data.m_ioctx.write("foo_rmxattr", bl21, sizeof(buf2), 0));
1018 bufferlist bl22;
1019 bl22.append(attr2_buf, sizeof(attr2_buf));
1020 // async setxattr
1021 AioTestDataPP test_data4;
1022 ASSERT_EQ("", test_data4.init());
1023 boost::scoped_ptr<AioCompletion> my_completion4
1024 (test_data.m_cluster.aio_create_completion
1025 ((void*)&test_data4, set_completion_completePP, set_completion_safePP));
1026 ASSERT_EQ(0, test_data.m_ioctx.aio_setxattr("foo_rmxattr", my_completion4.get(), attr2, bl22));
1027 {
1028 TestAlarm alarm;
1029 ASSERT_EQ(0, my_completion4->wait_for_complete());
1030 }
1031 ASSERT_EQ(0, my_completion4->get_return_value());
1032 // remove object
1033 ASSERT_EQ(0, test_data.m_ioctx.remove("foo_rmxattr"));
1034 // async rmxattr on non existing object
1035 AioTestDataPP test_data5;
1036 ASSERT_EQ("", test_data5.init());
1037 boost::scoped_ptr<AioCompletion> my_completion5
1038 (test_data.m_cluster.aio_create_completion
1039 ((void*)&test_data5, set_completion_completePP, set_completion_safePP));
1040 ASSERT_EQ(0, test_data.m_ioctx.aio_rmxattr("foo_rmxattr", my_completion5.get(), attr2));
1041 {
1042 TestAlarm alarm;
1043 ASSERT_EQ(0, my_completion5->wait_for_complete());
1044 }
1045 ASSERT_EQ(-ENOENT, my_completion5->get_return_value());
1046 }
1047
1048 TEST(LibRadosAio, XattrIter) {
1049 AioTestData test_data;
1050 ASSERT_EQ("", test_data.init());
1051 // Create an object with 2 attributes
1052 char buf[128];
1053 char attr1[] = "attr1";
1054 char attr1_buf[] = "foo bar baz";
1055 char attr2[] = "attr2";
1056 char attr2_buf[256];
1057 for (size_t j = 0; j < sizeof(attr2_buf); ++j) {
1058 attr2_buf[j] = j % 0xff;
1059 }
1060 memset(buf, 0xaa, sizeof(buf));
1061 ASSERT_EQ(0, rados_append(test_data.m_ioctx, "foo", buf, sizeof(buf)));
1062 ASSERT_EQ(0, rados_setxattr(test_data.m_ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf)));
1063 ASSERT_EQ(0, rados_setxattr(test_data.m_ioctx, "foo", attr2, attr2_buf, sizeof(attr2_buf)));
1064 // call async version of getxattrs and wait for completion
1065 rados_completion_t my_completion;
1066 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1067 set_completion_complete, set_completion_safe, &my_completion));
1068 rados_xattrs_iter_t iter;
1069 ASSERT_EQ(0, rados_aio_getxattrs(test_data.m_ioctx, "foo", my_completion, &iter));
1070 {
1071 TestAlarm alarm;
1072 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1073 }
1074 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1075 // loop over attributes
1076 int num_seen = 0;
1077 while (true) {
1078 const char *name;
1079 const char *val;
1080 size_t len;
1081 ASSERT_EQ(0, rados_getxattrs_next(iter, &name, &val, &len));
1082 if (name == NULL) {
1083 break;
1084 }
1085 ASSERT_LT(num_seen, 2);
1086 if ((strcmp(name, attr1) == 0) && (val != NULL) && (memcmp(val, attr1_buf, len) == 0)) {
1087 num_seen++;
1088 continue;
1089 }
1090 else if ((strcmp(name, attr2) == 0) && (val != NULL) && (memcmp(val, attr2_buf, len) == 0)) {
1091 num_seen++;
1092 continue;
1093 }
1094 else {
1095 ASSERT_EQ(0, 1);
1096 }
1097 }
1098 rados_getxattrs_end(iter);
1099 }
1100
1101 TEST(LibRadosIoPP, XattrListPP) {
1102 AioTestDataPP test_data;
1103 ASSERT_EQ("", test_data.init());
1104 // create an object with 2 attributes
1105 char buf[128];
1106 char attr1[] = "attr1";
1107 char attr1_buf[] = "foo bar baz";
1108 char attr2[] = "attr2";
1109 char attr2_buf[256];
1110 for (size_t j = 0; j < sizeof(attr2_buf); ++j) {
1111 attr2_buf[j] = j % 0xff;
1112 }
1113 memset(buf, 0xaa, sizeof(buf));
1114 bufferlist bl1;
1115 bl1.append(buf, sizeof(buf));
1116 ASSERT_EQ(0, test_data.m_ioctx.append("foo", bl1, sizeof(buf)));
1117 bufferlist bl2;
1118 bl2.append(attr1_buf, sizeof(attr1_buf));
1119 ASSERT_EQ(0, test_data.m_ioctx.setxattr("foo", attr1, bl2));
1120 bufferlist bl3;
1121 bl3.append(attr2_buf, sizeof(attr2_buf));
1122 ASSERT_EQ(0, test_data.m_ioctx.setxattr("foo", attr2, bl3));
1123 // call async version of getxattrs
1124 boost::scoped_ptr<AioCompletion> my_completion
1125 (test_data.m_cluster.aio_create_completion
1126 ((void*)&test_data, set_completion_completePP, set_completion_safePP));
1127 std::map<std::string, bufferlist> attrset;
1128 ASSERT_EQ(0, test_data.m_ioctx.aio_getxattrs("foo", my_completion.get(), attrset));
1129 {
1130 TestAlarm alarm;
1131 ASSERT_EQ(0, my_completion->wait_for_complete());
1132 }
1133 ASSERT_EQ(0, my_completion->get_return_value());
1134 for (std::map<std::string, bufferlist>::iterator i = attrset.begin();
1135 i != attrset.end(); ++i) {
1136 if (i->first == string(attr1)) {
1137 ASSERT_EQ(0, memcmp(i->second.c_str(), attr1_buf, sizeof(attr1_buf)));
1138 }
1139 else if (i->first == string(attr2)) {
1140 ASSERT_EQ(0, memcmp(i->second.c_str(), attr2_buf, sizeof(attr2_buf)));
1141 }
1142 else {
1143 ASSERT_EQ(0, 1);
1144 }
1145 }
1146 }
1147
1148 TEST(LibRadosAio, IsComplete) {
1149 AioTestData test_data;
1150 rados_completion_t my_completion;
1151 ASSERT_EQ("", test_data.init());
1152 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1153 set_completion_complete, set_completion_safe, &my_completion));
1154 char buf[128];
1155 memset(buf, 0xcc, sizeof(buf));
1156 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1157 my_completion, buf, sizeof(buf), 0));
1158 {
1159 TestAlarm alarm;
1160 sem_wait(test_data.m_sem);
1161 sem_wait(test_data.m_sem);
1162 }
1163 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1164 char buf2[128];
1165 memset(buf2, 0, sizeof(buf2));
1166 rados_completion_t my_completion2;
1167 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1168 set_completion_complete, set_completion_safe, &my_completion2));
1169 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1170 my_completion2, buf2, sizeof(buf2), 0));
1171 {
1172 TestAlarm alarm;
1173
1174 // Busy-wait until the AIO completes.
1175 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
1176 while (true) {
1177 int is_complete = rados_aio_is_complete(my_completion2);
1178 if (is_complete)
1179 break;
1180 }
1181 }
1182 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
1183 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
1184 rados_aio_release(my_completion);
1185 rados_aio_release(my_completion2);
1186 }
1187
1188 TEST(LibRadosAio, IsCompletePP) {
1189 AioTestDataPP test_data;
1190 ASSERT_EQ("", test_data.init());
1191 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1192 (void*)&test_data, set_completion_complete, set_completion_safe);
1193 AioCompletion *my_completion_null = NULL;
1194 ASSERT_NE(my_completion, my_completion_null);
1195 char buf[128];
1196 memset(buf, 0xcc, sizeof(buf));
1197 bufferlist bl1;
1198 bl1.append(buf, sizeof(buf));
1199 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1200 bl1, sizeof(buf), 0));
1201 {
1202 TestAlarm alarm;
1203 sem_wait(test_data.m_sem);
1204 sem_wait(test_data.m_sem);
1205 }
1206 ASSERT_EQ(0, my_completion->get_return_value());
1207 bufferlist bl2;
1208 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1209 (void*)&test_data, set_completion_complete, set_completion_safe);
1210 ASSERT_NE(my_completion2, my_completion_null);
1211 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
1212 &bl2, sizeof(buf), 0));
1213 {
1214 TestAlarm alarm;
1215
1216 // Busy-wait until the AIO completes.
1217 // Normally we wouldn't do this, but we want to test is_complete.
1218 while (true) {
1219 int is_complete = my_completion2->is_complete();
1220 if (is_complete)
1221 break;
1222 }
1223 }
1224 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
1225 ASSERT_EQ(sizeof(buf), bl2.length());
1226 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
1227 delete my_completion;
1228 delete my_completion2;
1229 }
1230
1231 TEST(LibRadosAio, IsSafe) {
1232 AioTestData test_data;
1233 rados_completion_t my_completion;
1234 ASSERT_EQ("", test_data.init());
1235 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1236 set_completion_complete, set_completion_safe, &my_completion));
1237 char buf[128];
1238 memset(buf, 0xcc, sizeof(buf));
1239 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1240 my_completion, buf, sizeof(buf), 0));
1241 {
1242 TestAlarm alarm;
1243
1244 // Busy-wait until the AIO completes.
1245 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
1246 while (true) {
1247 int is_safe = rados_aio_is_safe(my_completion);
1248 if (is_safe)
1249 break;
1250 }
1251 }
1252 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1253 char buf2[128];
1254 memset(buf2, 0, sizeof(buf2));
1255 rados_completion_t my_completion2;
1256 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1257 set_completion_complete, set_completion_safe, &my_completion2));
1258 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1259 my_completion2, buf2, sizeof(buf2), 0));
1260 {
1261 TestAlarm alarm;
1262 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1263 }
1264 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
1265 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
1266 rados_aio_release(my_completion);
1267 rados_aio_release(my_completion2);
1268 }
1269
1270 TEST(LibRadosAio, IsSafePP) {
1271 AioTestDataPP test_data;
1272 ASSERT_EQ("", test_data.init());
1273 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1274 (void*)&test_data, set_completion_complete, set_completion_safe);
1275 AioCompletion *my_completion_null = NULL;
1276 ASSERT_NE(my_completion, my_completion_null);
1277 char buf[128];
1278 memset(buf, 0xcc, sizeof(buf));
1279 bufferlist bl1;
1280 bl1.append(buf, sizeof(buf));
1281 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1282 bl1, sizeof(buf), 0));
1283 {
1284 TestAlarm alarm;
1285
1286 // Busy-wait until the AIO completes.
1287 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
1288 while (true) {
1289 int is_safe = my_completion->is_safe();
1290 if (is_safe)
1291 break;
1292 }
1293 }
1294 ASSERT_EQ(0, my_completion->get_return_value());
1295 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1296 (void*)&test_data, set_completion_complete, set_completion_safe);
1297 bufferlist bl2;
1298 ASSERT_NE(my_completion2, my_completion_null);
1299 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
1300 &bl2, sizeof(buf), 0));
1301 {
1302 TestAlarm alarm;
1303 ASSERT_EQ(0, my_completion2->wait_for_complete());
1304 }
1305 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
1306 ASSERT_EQ(sizeof(buf), bl2.length());
1307 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
1308 delete my_completion;
1309 delete my_completion2;
1310 }
1311
1312 TEST(LibRadosAio, ReturnValue) {
1313 AioTestData test_data;
1314 rados_completion_t my_completion;
1315 ASSERT_EQ("", test_data.init());
1316 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1317 set_completion_complete, set_completion_safe, &my_completion));
1318 char buf[128];
1319 memset(buf, 0, sizeof(buf));
1320 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "nonexistent",
1321 my_completion, buf, sizeof(buf), 0));
1322 {
1323 TestAlarm alarm;
1324 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1325 }
1326 ASSERT_EQ(-ENOENT, rados_aio_get_return_value(my_completion));
1327 rados_aio_release(my_completion);
1328 }
1329
1330 TEST(LibRadosAio, ReturnValuePP) {
1331 AioTestDataPP test_data;
1332 ASSERT_EQ("", test_data.init());
1333 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1334 (void*)&test_data, set_completion_complete, set_completion_safe);
1335 AioCompletion *my_completion_null = NULL;
1336 ASSERT_NE(my_completion, my_completion_null);
1337 bufferlist bl1;
1338 ASSERT_EQ(0, test_data.m_ioctx.aio_read("nonexistent",
1339 my_completion, &bl1, 128, 0));
1340 {
1341 TestAlarm alarm;
1342 ASSERT_EQ(0, my_completion->wait_for_complete());
1343 }
1344 ASSERT_EQ(-ENOENT, my_completion->get_return_value());
1345 delete my_completion;
1346 }
1347
1348 TEST(LibRadosAio, Flush) {
1349 AioTestData test_data;
1350 rados_completion_t my_completion;
1351 ASSERT_EQ("", test_data.init());
1352 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1353 set_completion_complete, set_completion_safe, &my_completion));
1354 char buf[128];
1355 memset(buf, 0xee, sizeof(buf));
1356 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1357 my_completion, buf, sizeof(buf), 0));
1358 ASSERT_EQ(0, rados_aio_flush(test_data.m_ioctx));
1359 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1360 char buf2[128];
1361 memset(buf2, 0, sizeof(buf2));
1362 rados_completion_t my_completion2;
1363 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1364 set_completion_complete, set_completion_safe, &my_completion2));
1365 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1366 my_completion2, buf2, sizeof(buf2), 0));
1367 {
1368 TestAlarm alarm;
1369 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1370 }
1371 ASSERT_EQ((int)sizeof(buf2), rados_aio_get_return_value(my_completion2));
1372 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
1373 rados_aio_release(my_completion);
1374 rados_aio_release(my_completion2);
1375 }
1376
1377 TEST(LibRadosAio, FlushPP) {
1378 AioTestDataPP test_data;
1379 ASSERT_EQ("", test_data.init());
1380 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1381 (void*)&test_data, set_completion_complete, set_completion_safe);
1382 AioCompletion *my_completion_null = NULL;
1383 ASSERT_NE(my_completion, my_completion_null);
1384 char buf[128];
1385 memset(buf, 0xee, sizeof(buf));
1386 bufferlist bl1;
1387 bl1.append(buf, sizeof(buf));
1388 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1389 bl1, sizeof(buf), 0));
1390 ASSERT_EQ(0, test_data.m_ioctx.aio_flush());
1391 ASSERT_EQ(0, my_completion->get_return_value());
1392 bufferlist bl2;
1393 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1394 (void*)&test_data, set_completion_complete, set_completion_safe);
1395 ASSERT_NE(my_completion2, my_completion_null);
1396 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
1397 &bl2, sizeof(buf), 0));
1398 {
1399 TestAlarm alarm;
1400 ASSERT_EQ(0, my_completion2->wait_for_complete());
1401 }
1402 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
1403 ASSERT_EQ(sizeof(buf), bl2.length());
1404 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
1405 delete my_completion;
1406 delete my_completion2;
1407 }
1408
1409 TEST(LibRadosAio, FlushAsync) {
1410 AioTestData test_data;
1411 rados_completion_t my_completion;
1412 ASSERT_EQ("", test_data.init());
1413 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1414 set_completion_complete, set_completion_safe, &my_completion));
1415 rados_completion_t flush_completion;
1416 ASSERT_EQ(0, rados_aio_create_completion(NULL, NULL, NULL, &flush_completion));
1417 char buf[128];
1418 memset(buf, 0xee, sizeof(buf));
1419 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1420 my_completion, buf, sizeof(buf), 0));
1421 ASSERT_EQ(0, rados_aio_flush_async(test_data.m_ioctx, flush_completion));
1422 {
1423 TestAlarm alarm;
1424 ASSERT_EQ(0, rados_aio_wait_for_complete(flush_completion));
1425 ASSERT_EQ(0, rados_aio_wait_for_safe(flush_completion));
1426 }
1427 ASSERT_EQ(1, rados_aio_is_complete(my_completion));
1428 ASSERT_EQ(1, rados_aio_is_safe(my_completion));
1429 ASSERT_EQ(1, rados_aio_is_complete(flush_completion));
1430 ASSERT_EQ(1, rados_aio_is_safe(flush_completion));
1431 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1432 char buf2[128];
1433 memset(buf2, 0, sizeof(buf2));
1434 rados_completion_t my_completion2;
1435 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1436 set_completion_complete, set_completion_safe, &my_completion2));
1437 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1438 my_completion2, buf2, sizeof(buf2), 0));
1439 {
1440 TestAlarm alarm;
1441 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1442 }
1443 ASSERT_EQ((int)sizeof(buf2), rados_aio_get_return_value(my_completion2));
1444 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
1445 rados_aio_release(my_completion);
1446 rados_aio_release(my_completion2);
1447 rados_aio_release(flush_completion);
1448 }
1449
1450 TEST(LibRadosAio, FlushAsyncPP) {
1451 AioTestDataPP test_data;
1452 ASSERT_EQ("", test_data.init());
1453 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1454 (void*)&test_data, set_completion_complete, set_completion_safe);
1455 AioCompletion *flush_completion =
1456 test_data.m_cluster.aio_create_completion(NULL, NULL, NULL);
1457 AioCompletion *my_completion_null = NULL;
1458 ASSERT_NE(my_completion, my_completion_null);
1459 char buf[128];
1460 memset(buf, 0xee, sizeof(buf));
1461 bufferlist bl1;
1462 bl1.append(buf, sizeof(buf));
1463 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1464 bl1, sizeof(buf), 0));
1465 ASSERT_EQ(0, test_data.m_ioctx.aio_flush_async(flush_completion));
1466 {
1467 TestAlarm alarm;
1468 ASSERT_EQ(0, flush_completion->wait_for_complete());
1469 ASSERT_EQ(0, flush_completion->wait_for_safe());
1470 }
1471 ASSERT_EQ(1, my_completion->is_complete());
1472 ASSERT_EQ(1, my_completion->is_safe());
1473 ASSERT_EQ(1, flush_completion->is_complete());
1474 ASSERT_EQ(1, flush_completion->is_safe());
1475 ASSERT_EQ(0, my_completion->get_return_value());
1476 bufferlist bl2;
1477 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1478 (void*)&test_data, set_completion_complete, set_completion_safe);
1479 ASSERT_NE(my_completion2, my_completion_null);
1480 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
1481 &bl2, sizeof(buf), 0));
1482 {
1483 TestAlarm alarm;
1484 ASSERT_EQ(0, my_completion2->wait_for_complete());
1485 }
1486 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
1487 ASSERT_EQ(sizeof(buf), bl2.length());
1488 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
1489 delete my_completion;
1490 delete my_completion2;
1491 delete flush_completion;
1492 }
1493
1494 TEST(LibRadosAio, RoundTripWriteFull) {
1495 AioTestData test_data;
1496 rados_completion_t my_completion, my_completion2, my_completion3;
1497 ASSERT_EQ("", test_data.init());
1498 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1499 set_completion_complete, set_completion_safe, &my_completion));
1500 char buf[128];
1501 memset(buf, 0xcc, sizeof(buf));
1502 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1503 my_completion, buf, sizeof(buf), 0));
1504 {
1505 TestAlarm alarm;
1506 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1507 }
1508 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1509 char buf2[64];
1510 memset(buf2, 0xdd, sizeof(buf2));
1511 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1512 set_completion_complete, set_completion_safe, &my_completion2));
1513 ASSERT_EQ(0, rados_aio_write_full(test_data.m_ioctx, "foo",
1514 my_completion2, buf2, sizeof(buf2)));
1515 {
1516 TestAlarm alarm;
1517 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1518 }
1519 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
1520 char buf3[sizeof(buf) + sizeof(buf2)];
1521 memset(buf3, 0, sizeof(buf3));
1522 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1523 set_completion_complete, set_completion_safe, &my_completion3));
1524 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1525 my_completion3, buf3, sizeof(buf3), 0));
1526 {
1527 TestAlarm alarm;
1528 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
1529 }
1530 ASSERT_EQ((int)sizeof(buf2), rados_aio_get_return_value(my_completion3));
1531 ASSERT_EQ(0, memcmp(buf3, buf2, sizeof(buf2)));
1532 rados_aio_release(my_completion);
1533 rados_aio_release(my_completion2);
1534 rados_aio_release(my_completion3);
1535 }
1536
1537 TEST(LibRadosAio, RoundTripWriteFullPP) {
1538 AioTestDataPP test_data;
1539 ASSERT_EQ("", test_data.init());
1540 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1541 (void*)&test_data, set_completion_complete, set_completion_safe);
1542 AioCompletion *my_completion_null = NULL;
1543 ASSERT_NE(my_completion, my_completion_null);
1544 char buf[128];
1545 memset(buf, 0xcc, sizeof(buf));
1546 bufferlist bl1;
1547 bl1.append(buf, sizeof(buf));
1548 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1549 bl1, sizeof(buf), 0));
1550 {
1551 TestAlarm alarm;
1552 ASSERT_EQ(0, my_completion->wait_for_complete());
1553 }
1554 ASSERT_EQ(0, my_completion->get_return_value());
1555 char buf2[64];
1556 memset(buf2, 0xdd, sizeof(buf2));
1557 bufferlist bl2;
1558 bl2.append(buf2, sizeof(buf2));
1559 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1560 (void*)&test_data, set_completion_complete, set_completion_safe);
1561 ASSERT_NE(my_completion2, my_completion_null);
1562 ASSERT_EQ(0, test_data.m_ioctx.aio_write_full("foo", my_completion2, bl2));
1563 {
1564 TestAlarm alarm;
1565 ASSERT_EQ(0, my_completion2->wait_for_complete());
1566 }
1567 ASSERT_EQ(0, my_completion2->get_return_value());
1568 bufferlist bl3;
1569 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
1570 (void*)&test_data, set_completion_complete, set_completion_safe);
1571 ASSERT_NE(my_completion3, my_completion_null);
1572 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion3,
1573 &bl3, sizeof(buf), 0));
1574 {
1575 TestAlarm alarm;
1576 ASSERT_EQ(0, my_completion3->wait_for_complete());
1577 }
1578 ASSERT_EQ((int)sizeof(buf2), my_completion3->get_return_value());
1579 ASSERT_EQ(sizeof(buf2), bl3.length());
1580 ASSERT_EQ(0, memcmp(bl3.c_str(), buf2, sizeof(buf2)));
1581 delete my_completion;
1582 delete my_completion2;
1583 delete my_completion3;
1584 }
1585
1586 //using ObjectWriteOperation/ObjectReadOperation with iohint
1587 TEST(LibRadosAio, RoundTripWriteFullPP2)
1588 {
1589 Rados cluster;
1590 std::string pool_name = get_temp_pool_name();
1591 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
1592 IoCtx ioctx;
1593 cluster.ioctx_create(pool_name.c_str(), ioctx);
1594
1595 boost::scoped_ptr<AioCompletion> my_completion1(cluster.aio_create_completion(0, 0, 0));
1596 ObjectWriteOperation op;
1597 char buf[128];
1598 memset(buf, 0xcc, sizeof(buf));
1599 bufferlist bl;
1600 bl.append(buf);
1601
1602 op.write_full(bl);
1603 op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
1604 ioctx.aio_operate("test_obj", my_completion1.get(), &op);
1605 {
1606 TestAlarm alarm;
1607 ASSERT_EQ(0, my_completion1->wait_for_complete());
1608 }
1609 EXPECT_EQ(0, my_completion1->get_return_value());
1610
1611 boost::scoped_ptr<AioCompletion> my_completion2(cluster.aio_create_completion(0, 0, 0));
1612 bl.clear();
1613 ObjectReadOperation op1;
1614 op1.read(0, sizeof(buf), &bl, NULL);
1615 op1.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED|LIBRADOS_OP_FLAG_FADVISE_RANDOM);
1616 ioctx.aio_operate("test_obj", my_completion2.get(), &op1, 0);
1617 {
1618 TestAlarm alarm;
1619 ASSERT_EQ(0, my_completion2->wait_for_complete());
1620 }
1621 EXPECT_EQ(0, my_completion2->get_return_value());
1622 ASSERT_EQ(0, memcmp(buf, bl.c_str(), sizeof(buf)));
1623
1624 ioctx.remove("test_obj");
1625 destroy_one_pool_pp(pool_name, cluster);
1626 }
1627
1628 TEST(LibRadosAio, RoundTripWriteSame) {
1629 AioTestData test_data;
1630 rados_completion_t my_completion, my_completion2, my_completion3;
1631 ASSERT_EQ("", test_data.init());
1632 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1633 set_completion_complete, set_completion_safe, &my_completion));
1634 char full[128];
1635 memset(full, 0xcc, sizeof(full));
1636 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1637 my_completion, full, sizeof(full), 0));
1638 {
1639 TestAlarm alarm;
1640 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1641 }
1642 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1643 /* write the same buf four times */
1644 char buf[32];
1645 size_t ws_write_len = sizeof(full);
1646 memset(buf, 0xdd, sizeof(buf));
1647 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1648 set_completion_complete, set_completion_safe, &my_completion2));
1649 ASSERT_EQ(0, rados_aio_writesame(test_data.m_ioctx, "foo",
1650 my_completion2, buf, sizeof(buf),
1651 ws_write_len, 0));
1652 {
1653 TestAlarm alarm;
1654 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1655 }
1656 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
1657 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1658 set_completion_complete, set_completion_safe, &my_completion3));
1659 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1660 my_completion3, full, sizeof(full), 0));
1661 {
1662 TestAlarm alarm;
1663 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
1664 }
1665 ASSERT_EQ((int)sizeof(full), rados_aio_get_return_value(my_completion3));
1666 for (char *cmp = full; cmp < full + sizeof(full); cmp += sizeof(buf)) {
1667 ASSERT_EQ(0, memcmp(cmp, buf, sizeof(buf)));
1668 }
1669 rados_aio_release(my_completion);
1670 rados_aio_release(my_completion2);
1671 rados_aio_release(my_completion3);
1672 }
1673
1674 TEST(LibRadosAio, RoundTripWriteSamePP) {
1675 AioTestDataPP test_data;
1676 ASSERT_EQ("", test_data.init());
1677 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1678 (void*)&test_data, set_completion_complete, set_completion_safe);
1679 AioCompletion *my_completion_null = NULL;
1680 ASSERT_NE(my_completion, my_completion_null);
1681 char full[128];
1682 memset(full, 0xcc, sizeof(full));
1683 bufferlist bl1;
1684 bl1.append(full, sizeof(full));
1685 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1686 bl1, sizeof(full), 0));
1687 {
1688 TestAlarm alarm;
1689 ASSERT_EQ(0, my_completion->wait_for_complete());
1690 }
1691 ASSERT_EQ(0, my_completion->get_return_value());
1692 /* write the same buf four times */
1693 char buf[32];
1694 size_t ws_write_len = sizeof(full);
1695 memset(buf, 0xdd, sizeof(buf));
1696 bufferlist bl2;
1697 bl2.append(buf, sizeof(buf));
1698 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1699 (void*)&test_data, set_completion_complete, set_completion_safe);
1700 ASSERT_NE(my_completion2, my_completion_null);
1701 ASSERT_EQ(0, test_data.m_ioctx.aio_writesame("foo", my_completion2, bl2,
1702 ws_write_len, 0));
1703 {
1704 TestAlarm alarm;
1705 ASSERT_EQ(0, my_completion2->wait_for_complete());
1706 }
1707 ASSERT_EQ(0, my_completion2->get_return_value());
1708 bufferlist bl3;
1709 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
1710 (void*)&test_data, set_completion_complete, set_completion_safe);
1711 ASSERT_NE(my_completion3, my_completion_null);
1712 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion3,
1713 &bl3, sizeof(full), 0));
1714 {
1715 TestAlarm alarm;
1716 ASSERT_EQ(0, my_completion3->wait_for_complete());
1717 }
1718 ASSERT_EQ((int)sizeof(full), my_completion3->get_return_value());
1719 ASSERT_EQ(sizeof(full), bl3.length());
1720 for (char *cmp = bl3.c_str(); cmp < bl3.c_str() + bl3.length();
1721 cmp += sizeof(buf)) {
1722 ASSERT_EQ(0, memcmp(cmp, buf, sizeof(buf)));
1723 }
1724 delete my_completion;
1725 delete my_completion2;
1726 delete my_completion3;
1727 }
1728
1729 TEST(LibRadosAio, RoundTripWriteSamePP2)
1730 {
1731 Rados cluster;
1732 std::string pool_name = get_temp_pool_name();
1733 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
1734 IoCtx ioctx;
1735 cluster.ioctx_create(pool_name.c_str(), ioctx);
1736
1737 boost::scoped_ptr<AioCompletion>
1738 wr_cmpl(cluster.aio_create_completion(0, 0, 0));
1739 ObjectWriteOperation op;
1740 char buf[128];
1741 memset(buf, 0xcc, sizeof(buf));
1742 bufferlist bl;
1743 bl.append(buf, sizeof(buf));
1744
1745 op.writesame(0, sizeof(buf) * 4, bl);
1746 op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
1747 ioctx.aio_operate("test_obj", wr_cmpl.get(), &op);
1748 {
1749 TestAlarm alarm;
1750 ASSERT_EQ(0, wr_cmpl->wait_for_complete());
1751 }
1752 EXPECT_EQ(0, wr_cmpl->get_return_value());
1753
1754 boost::scoped_ptr<AioCompletion>
1755 rd_cmpl(cluster.aio_create_completion(0, 0, 0));
1756 char *cmp;
1757 char full[sizeof(buf) * 4];
1758 memset(full, 0, sizeof(full));
1759 bufferlist fl;
1760 fl.append(full, sizeof(full));
1761 ObjectReadOperation op1;
1762 op1.read(0, sizeof(full), &fl, NULL);
1763 op1.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
1764 ioctx.aio_operate("test_obj", rd_cmpl.get(), &op1, 0);
1765 {
1766 TestAlarm alarm;
1767 ASSERT_EQ(0, rd_cmpl->wait_for_complete());
1768 }
1769 EXPECT_EQ(0, rd_cmpl->get_return_value());
1770 for (cmp = fl.c_str(); cmp < fl.c_str() + fl.length(); cmp += sizeof(buf)) {
1771 ASSERT_EQ(0, memcmp(cmp, buf, sizeof(buf)));
1772 }
1773
1774 ioctx.remove("test_obj");
1775 destroy_one_pool_pp(pool_name, cluster);
1776 }
1777
1778 TEST(LibRadosAio, SimpleStat) {
1779 AioTestData test_data;
1780 rados_completion_t my_completion;
1781 ASSERT_EQ("", test_data.init());
1782 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1783 set_completion_complete, set_completion_safe, &my_completion));
1784 char buf[128];
1785 memset(buf, 0xcc, sizeof(buf));
1786 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1787 my_completion, buf, sizeof(buf), 0));
1788 {
1789 TestAlarm alarm;
1790 sem_wait(test_data.m_sem);
1791 sem_wait(test_data.m_sem);
1792 }
1793 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1794 uint64_t psize;
1795 time_t pmtime;
1796 rados_completion_t my_completion2;
1797 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1798 set_completion_complete, set_completion_safe, &my_completion2));
1799 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
1800 my_completion2, &psize, &pmtime));
1801 {
1802 TestAlarm alarm;
1803 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1804 }
1805 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
1806 ASSERT_EQ(sizeof(buf), psize);
1807 rados_aio_release(my_completion);
1808 rados_aio_release(my_completion2);
1809 }
1810
1811 TEST(LibRadosAio, SimpleStatPP) {
1812 AioTestDataPP test_data;
1813 ASSERT_EQ("", test_data.init());
1814 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1815 (void*)&test_data, set_completion_complete, set_completion_safe);
1816 AioCompletion *my_completion_null = NULL;
1817 ASSERT_NE(my_completion, my_completion_null);
1818 char buf[128];
1819 memset(buf, 0xcc, sizeof(buf));
1820 bufferlist bl1;
1821 bl1.append(buf, sizeof(buf));
1822 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1823 bl1, sizeof(buf), 0));
1824 {
1825 TestAlarm alarm;
1826 sem_wait(test_data.m_sem);
1827 sem_wait(test_data.m_sem);
1828 }
1829 ASSERT_EQ(0, my_completion->get_return_value());
1830 uint64_t psize;
1831 time_t pmtime;
1832 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1833 (void*)&test_data, set_completion_complete, set_completion_safe);
1834 ASSERT_NE(my_completion2, my_completion_null);
1835 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion2,
1836 &psize, &pmtime));
1837 {
1838 TestAlarm alarm;
1839 ASSERT_EQ(0, my_completion2->wait_for_complete());
1840 }
1841 ASSERT_EQ(0, my_completion2->get_return_value());
1842 ASSERT_EQ(sizeof(buf), psize);
1843 delete my_completion;
1844 delete my_completion2;
1845 }
1846
1847 TEST(LibRadosAio, SimpleStatNS) {
1848 AioTestData test_data;
1849 rados_completion_t my_completion;
1850 ASSERT_EQ("", test_data.init());
1851 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1852 set_completion_complete, set_completion_safe, &my_completion));
1853 char buf[128];
1854 memset(buf, 0xcc, sizeof(buf));
1855 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1856 my_completion, buf, sizeof(buf), 0));
1857 {
1858 TestAlarm alarm;
1859 sem_wait(test_data.m_sem);
1860 sem_wait(test_data.m_sem);
1861 }
1862 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1863 rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
1864 char buf2[64];
1865 memset(buf2, 0xbb, sizeof(buf2));
1866 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1867 set_completion_complete, set_completion_safe, &my_completion));
1868 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1869 my_completion, buf2, sizeof(buf2), 0));
1870 {
1871 TestAlarm alarm;
1872 sem_wait(test_data.m_sem);
1873 sem_wait(test_data.m_sem);
1874 }
1875 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1876 uint64_t psize;
1877 time_t pmtime;
1878 rados_completion_t my_completion2;
1879 rados_ioctx_set_namespace(test_data.m_ioctx, "");
1880 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1881 set_completion_complete, set_completion_safe, &my_completion2));
1882 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
1883 my_completion2, &psize, &pmtime));
1884 {
1885 TestAlarm alarm;
1886 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1887 }
1888 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
1889 ASSERT_EQ(sizeof(buf), psize);
1890
1891 rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
1892 rados_completion_t my_completion3;
1893 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1894 set_completion_complete, set_completion_safe, &my_completion3));
1895 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
1896 my_completion3, &psize, &pmtime));
1897 {
1898 TestAlarm alarm;
1899 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
1900 }
1901 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3));
1902 ASSERT_EQ(sizeof(buf2), psize);
1903
1904 rados_aio_release(my_completion);
1905 rados_aio_release(my_completion2);
1906 rados_aio_release(my_completion3);
1907 }
1908
1909 TEST(LibRadosAio, SimpleStatPPNS) {
1910 AioTestDataPP test_data;
1911 ASSERT_EQ("", test_data.init());
1912 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1913 (void*)&test_data, set_completion_complete, set_completion_safe);
1914 AioCompletion *my_completion_null = NULL;
1915 ASSERT_NE(my_completion, my_completion_null);
1916 char buf[128];
1917 memset(buf, 0xcc, sizeof(buf));
1918 bufferlist bl1;
1919 bl1.append(buf, sizeof(buf));
1920 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1921 bl1, sizeof(buf), 0));
1922 {
1923 TestAlarm alarm;
1924 sem_wait(test_data.m_sem);
1925 sem_wait(test_data.m_sem);
1926 }
1927 ASSERT_EQ(0, my_completion->get_return_value());
1928 uint64_t psize;
1929 time_t pmtime;
1930 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1931 (void*)&test_data, set_completion_complete, set_completion_safe);
1932 ASSERT_NE(my_completion2, my_completion_null);
1933 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion2,
1934 &psize, &pmtime));
1935 {
1936 TestAlarm alarm;
1937 ASSERT_EQ(0, my_completion2->wait_for_complete());
1938 }
1939 ASSERT_EQ(0, my_completion2->get_return_value());
1940 ASSERT_EQ(sizeof(buf), psize);
1941 delete my_completion;
1942 delete my_completion2;
1943 }
1944
1945 TEST(LibRadosAio, StatRemove) {
1946 AioTestData test_data;
1947 rados_completion_t my_completion;
1948 ASSERT_EQ("", test_data.init());
1949 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1950 set_completion_complete, set_completion_safe, &my_completion));
1951 char buf[128];
1952 memset(buf, 0xcc, sizeof(buf));
1953 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1954 my_completion, buf, sizeof(buf), 0));
1955 {
1956 TestAlarm alarm;
1957 sem_wait(test_data.m_sem);
1958 sem_wait(test_data.m_sem);
1959 }
1960 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1961 uint64_t psize;
1962 time_t pmtime;
1963 rados_completion_t my_completion2;
1964 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1965 set_completion_complete, set_completion_safe, &my_completion2));
1966 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
1967 my_completion2, &psize, &pmtime));
1968 {
1969 TestAlarm alarm;
1970 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1971 }
1972 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
1973 ASSERT_EQ(sizeof(buf), psize);
1974 rados_completion_t my_completion3;
1975 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1976 set_completion_complete, set_completion_safe, &my_completion3));
1977 ASSERT_EQ(0, rados_aio_remove(test_data.m_ioctx, "foo", my_completion3));
1978 {
1979 TestAlarm alarm;
1980 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
1981 }
1982 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3));
1983 uint64_t psize2;
1984 time_t pmtime2;
1985 rados_completion_t my_completion4;
1986 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
1987 set_completion_complete, set_completion_safe, &my_completion4));
1988 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
1989 my_completion4, &psize2, &pmtime2));
1990 {
1991 TestAlarm alarm;
1992 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4));
1993 }
1994 ASSERT_EQ(-ENOENT, rados_aio_get_return_value(my_completion4));
1995 rados_aio_release(my_completion);
1996 rados_aio_release(my_completion2);
1997 rados_aio_release(my_completion3);
1998 rados_aio_release(my_completion4);
1999 }
2000
2001 TEST(LibRadosAio, StatRemovePP) {
2002 AioTestDataPP test_data;
2003 ASSERT_EQ("", test_data.init());
2004 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2005 (void*)&test_data, set_completion_complete, set_completion_safe);
2006 AioCompletion *my_completion_null = NULL;
2007 ASSERT_NE(my_completion, my_completion_null);
2008 char buf[128];
2009 memset(buf, 0xcc, sizeof(buf));
2010 bufferlist bl1;
2011 bl1.append(buf, sizeof(buf));
2012 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
2013 bl1, sizeof(buf), 0));
2014 {
2015 TestAlarm alarm;
2016 sem_wait(test_data.m_sem);
2017 sem_wait(test_data.m_sem);
2018 }
2019 ASSERT_EQ(0, my_completion->get_return_value());
2020 uint64_t psize;
2021 time_t pmtime;
2022 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
2023 (void*)&test_data, set_completion_complete, set_completion_safe);
2024 ASSERT_NE(my_completion2, my_completion_null);
2025 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion2,
2026 &psize, &pmtime));
2027 {
2028 TestAlarm alarm;
2029 ASSERT_EQ(0, my_completion2->wait_for_complete());
2030 }
2031 ASSERT_EQ(0, my_completion2->get_return_value());
2032 ASSERT_EQ(sizeof(buf), psize);
2033 uint64_t psize2;
2034 time_t pmtime2;
2035 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
2036 (void*)&test_data, set_completion_complete, set_completion_safe);
2037 ASSERT_NE(my_completion3, my_completion_null);
2038 ASSERT_EQ(0, test_data.m_ioctx.aio_remove("foo", my_completion3));
2039 {
2040 TestAlarm alarm;
2041 ASSERT_EQ(0, my_completion3->wait_for_complete());
2042 }
2043 ASSERT_EQ(0, my_completion3->get_return_value());
2044
2045 AioCompletion *my_completion4 = test_data.m_cluster.aio_create_completion(
2046 (void*)&test_data, set_completion_complete, set_completion_safe);
2047 ASSERT_NE(my_completion4, my_completion_null);
2048 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion4,
2049 &psize2, &pmtime2));
2050 {
2051 TestAlarm alarm;
2052 ASSERT_EQ(0, my_completion4->wait_for_complete());
2053 }
2054 ASSERT_EQ(-ENOENT, my_completion4->get_return_value());
2055 delete my_completion;
2056 delete my_completion2;
2057 delete my_completion3;
2058 delete my_completion4;
2059 }
2060
2061 TEST(LibRadosAio, ExecuteClass) {
2062 AioTestData test_data;
2063 rados_completion_t my_completion;
2064 ASSERT_EQ("", test_data.init());
2065 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2066 set_completion_complete, set_completion_safe, &my_completion));
2067 char buf[128];
2068 memset(buf, 0xcc, sizeof(buf));
2069 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
2070 my_completion, buf, sizeof(buf), 0));
2071 {
2072 TestAlarm alarm;
2073 sem_wait(test_data.m_sem);
2074 sem_wait(test_data.m_sem);
2075 }
2076 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
2077 rados_completion_t my_completion2;
2078 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2079 set_completion_complete, set_completion_safe, &my_completion2));
2080 char out[128];
2081 ASSERT_EQ(0, rados_aio_exec(test_data.m_ioctx, "foo", my_completion2,
2082 "hello", "say_hello", NULL, 0, out, sizeof(out)));
2083 {
2084 TestAlarm alarm;
2085 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
2086 }
2087 ASSERT_EQ(13, rados_aio_get_return_value(my_completion2));
2088 ASSERT_EQ(0, strncmp("Hello, world!", out, 13));
2089 rados_aio_release(my_completion);
2090 rados_aio_release(my_completion2);
2091 }
2092
2093 TEST(LibRadosAio, ExecuteClassPP) {
2094 AioTestDataPP test_data;
2095 ASSERT_EQ("", test_data.init());
2096 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2097 (void*)&test_data, set_completion_complete, set_completion_safe);
2098 AioCompletion *my_completion_null = NULL;
2099 ASSERT_NE(my_completion, my_completion_null);
2100 char buf[128];
2101 memset(buf, 0xcc, sizeof(buf));
2102 bufferlist bl1;
2103 bl1.append(buf, sizeof(buf));
2104 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
2105 bl1, sizeof(buf), 0));
2106 {
2107 TestAlarm alarm;
2108 sem_wait(test_data.m_sem);
2109 sem_wait(test_data.m_sem);
2110 }
2111 ASSERT_EQ(0, my_completion->get_return_value());
2112 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
2113 (void*)&test_data, set_completion_complete, set_completion_safe);
2114 ASSERT_NE(my_completion2, my_completion_null);
2115 bufferlist in, out;
2116 ASSERT_EQ(0, test_data.m_ioctx.aio_exec("foo", my_completion2,
2117 "hello", "say_hello", in, &out));
2118 {
2119 TestAlarm alarm;
2120 ASSERT_EQ(0, my_completion2->wait_for_complete());
2121 }
2122 ASSERT_EQ(0, my_completion2->get_return_value());
2123 ASSERT_EQ(std::string("Hello, world!"), std::string(out.c_str(), out.length()));
2124 delete my_completion;
2125 delete my_completion2;
2126 }
2127
2128 using std::string;
2129 using std::map;
2130 using std::set;
2131
2132 TEST(LibRadosAio, OmapPP) {
2133 Rados cluster;
2134 std::string pool_name = get_temp_pool_name();
2135 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
2136 IoCtx ioctx;
2137 cluster.ioctx_create(pool_name.c_str(), ioctx);
2138
2139 string header_str = "baz";
2140 bufferptr bp(header_str.c_str(), header_str.size() + 1);
2141 bufferlist header_to_set;
2142 header_to_set.push_back(bp);
2143 map<string, bufferlist> to_set;
2144 {
2145 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
2146 ObjectWriteOperation op;
2147 to_set["foo"] = header_to_set;
2148 to_set["foo2"] = header_to_set;
2149 to_set["qfoo3"] = header_to_set;
2150 op.omap_set(to_set);
2151
2152 op.omap_set_header(header_to_set);
2153
2154 ioctx.aio_operate("test_obj", my_completion.get(), &op);
2155 {
2156 TestAlarm alarm;
2157 ASSERT_EQ(0, my_completion->wait_for_complete());
2158 }
2159 EXPECT_EQ(0, my_completion->get_return_value());
2160 }
2161
2162 {
2163 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
2164 ObjectReadOperation op;
2165 map<string, pair<bufferlist, int> > assertions;
2166 bufferlist val;
2167 val.append(string("bar"));
2168 assertions["foo"] = pair<bufferlist, int>(val, CEPH_OSD_CMPXATTR_OP_EQ);
2169
2170 int r;
2171 op.omap_cmp(assertions, &r);
2172
2173 ioctx.aio_operate("test_obj", my_completion.get(), &op, 0);
2174 {
2175 TestAlarm alarm;
2176 ASSERT_EQ(0, my_completion->wait_for_complete());
2177 }
2178 EXPECT_EQ(-ECANCELED, my_completion->get_return_value());
2179 ASSERT_EQ(-ECANCELED, r);
2180 }
2181
2182 {
2183 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
2184 ObjectReadOperation op;
2185
2186 set<string> set_got;
2187 map<string, bufferlist> map_got;
2188
2189 set<string> to_get;
2190 map<string, bufferlist> got3;
2191
2192 map<string, bufferlist> got4;
2193
2194 bufferlist header;
2195
2196 op.omap_get_keys2("", 1, &set_got, nullptr, 0);
2197 op.omap_get_vals2("foo", 1, &map_got, nullptr, 0);
2198
2199 to_get.insert("foo");
2200 to_get.insert("qfoo3");
2201 op.omap_get_vals_by_keys(to_get, &got3, 0);
2202
2203 op.omap_get_header(&header, 0);
2204
2205 op.omap_get_vals2("foo2", "q", 1, &got4, nullptr, 0);
2206
2207 ioctx.aio_operate("test_obj", my_completion.get(), &op, 0);
2208 {
2209 TestAlarm alarm;
2210 ASSERT_EQ(0, my_completion->wait_for_complete());
2211 }
2212 EXPECT_EQ(0, my_completion->get_return_value());
2213
2214 ASSERT_EQ(header.length(), header_to_set.length());
2215 ASSERT_EQ(set_got.size(), (unsigned)1);
2216 ASSERT_EQ(*set_got.begin(), "foo");
2217 ASSERT_EQ(map_got.size(), (unsigned)1);
2218 ASSERT_EQ(map_got.begin()->first, "foo2");
2219 ASSERT_EQ(got3.size(), (unsigned)2);
2220 ASSERT_EQ(got3.begin()->first, "foo");
2221 ASSERT_EQ(got3.rbegin()->first, "qfoo3");
2222 ASSERT_EQ(got4.size(), (unsigned)1);
2223 ASSERT_EQ(got4.begin()->first, "qfoo3");
2224 }
2225
2226 {
2227 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
2228 ObjectWriteOperation op;
2229 set<string> to_remove;
2230 to_remove.insert("foo2");
2231 op.omap_rm_keys(to_remove);
2232 ioctx.aio_operate("test_obj", my_completion.get(), &op);
2233 {
2234 TestAlarm alarm;
2235 ASSERT_EQ(0, my_completion->wait_for_complete());
2236 }
2237 EXPECT_EQ(0, my_completion->get_return_value());
2238 }
2239
2240 {
2241 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
2242 ObjectReadOperation op;
2243
2244 set<string> set_got;
2245 op.omap_get_keys2("", -1, &set_got, nullptr, 0);
2246 ioctx.aio_operate("test_obj", my_completion.get(), &op, 0);
2247 {
2248 TestAlarm alarm;
2249 ASSERT_EQ(0, my_completion->wait_for_complete());
2250 }
2251 EXPECT_EQ(0, my_completion->get_return_value());
2252 ASSERT_EQ(set_got.size(), (unsigned)2);
2253 }
2254
2255 {
2256 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
2257 ObjectWriteOperation op;
2258 op.omap_clear();
2259 ioctx.aio_operate("test_obj", my_completion.get(), &op);
2260 {
2261 TestAlarm alarm;
2262 ASSERT_EQ(0, my_completion->wait_for_complete());
2263 }
2264 EXPECT_EQ(0, my_completion->get_return_value());
2265 }
2266
2267 {
2268 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
2269 ObjectReadOperation op;
2270
2271 set<string> set_got;
2272 op.omap_get_keys2("", -1, &set_got, nullptr, 0);
2273 ioctx.aio_operate("test_obj", my_completion.get(), &op, 0);
2274 {
2275 TestAlarm alarm;
2276 ASSERT_EQ(0, my_completion->wait_for_complete());
2277 }
2278 EXPECT_EQ(0, my_completion->get_return_value());
2279 ASSERT_EQ(set_got.size(), (unsigned)0);
2280 }
2281
2282 // omap_clear clears header *and* keys
2283 {
2284 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
2285 ObjectWriteOperation op;
2286 bufferlist bl;
2287 bl.append("some data");
2288 map<string,bufferlist> to_set;
2289 to_set["foo"] = bl;
2290 to_set["foo2"] = bl;
2291 to_set["qfoo3"] = bl;
2292 op.omap_set(to_set);
2293 op.omap_set_header(bl);
2294 ioctx.aio_operate("foo3", my_completion.get(), &op);
2295 {
2296 TestAlarm alarm;
2297 ASSERT_EQ(0, my_completion->wait_for_complete());
2298 }
2299 EXPECT_EQ(0, my_completion->get_return_value());
2300 }
2301 {
2302 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
2303 ObjectWriteOperation op;
2304 op.omap_clear();
2305 ioctx.aio_operate("foo3", my_completion.get(), &op);
2306 {
2307 TestAlarm alarm;
2308 ASSERT_EQ(0, my_completion->wait_for_complete());
2309 }
2310 EXPECT_EQ(0, my_completion->get_return_value());
2311 }
2312 {
2313 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
2314 ObjectReadOperation op;
2315 set<string> set_got;
2316 bufferlist hdr;
2317 op.omap_get_keys2("", -1, &set_got, nullptr, 0);
2318 op.omap_get_header(&hdr, NULL);
2319 ioctx.aio_operate("foo3", my_completion.get(), &op, 0);
2320 {
2321 TestAlarm alarm;
2322 ASSERT_EQ(0, my_completion->wait_for_complete());
2323 }
2324 EXPECT_EQ(0, my_completion->get_return_value());
2325 ASSERT_EQ(set_got.size(), (unsigned)0);
2326 ASSERT_EQ(hdr.length(), 0u);
2327 }
2328
2329 ioctx.remove("test_obj");
2330 destroy_one_pool_pp(pool_name, cluster);
2331 }
2332
2333 TEST(LibRadosAio, MultiWrite) {
2334 AioTestData test_data;
2335 rados_completion_t my_completion, my_completion2, my_completion3;
2336 ASSERT_EQ("", test_data.init());
2337 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2338 set_completion_complete, set_completion_safe, &my_completion));
2339 char buf[128];
2340 memset(buf, 0xcc, sizeof(buf));
2341 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
2342 my_completion, buf, sizeof(buf), 0));
2343 {
2344 TestAlarm alarm;
2345 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
2346 }
2347 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
2348
2349 char buf2[64];
2350 memset(buf2, 0xdd, sizeof(buf2));
2351 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2352 set_completion_complete, set_completion_safe, &my_completion2));
2353 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
2354 my_completion2, buf2, sizeof(buf2), sizeof(buf)));
2355 {
2356 TestAlarm alarm;
2357 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
2358 }
2359 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
2360
2361 char buf3[(sizeof(buf) + sizeof(buf2)) * 3];
2362 memset(buf3, 0, sizeof(buf3));
2363 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2364 set_completion_complete, set_completion_safe, &my_completion3));
2365 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
2366 my_completion3, buf3, sizeof(buf3), 0));
2367 {
2368 TestAlarm alarm;
2369 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
2370 }
2371 ASSERT_EQ((int)(sizeof(buf) + sizeof(buf2)), rados_aio_get_return_value(my_completion3));
2372 ASSERT_EQ(0, memcmp(buf3, buf, sizeof(buf)));
2373 ASSERT_EQ(0, memcmp(buf3 + sizeof(buf), buf2, sizeof(buf2)));
2374 rados_aio_release(my_completion);
2375 rados_aio_release(my_completion2);
2376 rados_aio_release(my_completion3);
2377 }
2378
2379 TEST(LibRadosAio, MultiWritePP) {
2380 AioTestDataPP test_data;
2381 ASSERT_EQ("", test_data.init());
2382 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2383 (void*)&test_data, set_completion_complete, set_completion_safe);
2384 AioCompletion *my_completion_null = NULL;
2385 ASSERT_NE(my_completion, my_completion_null);
2386 char buf[128];
2387 memset(buf, 0xcc, sizeof(buf));
2388 bufferlist bl1;
2389 bl1.append(buf, sizeof(buf));
2390 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
2391 bl1, sizeof(buf), 0));
2392 {
2393 TestAlarm alarm;
2394 ASSERT_EQ(0, my_completion->wait_for_complete());
2395 }
2396 ASSERT_EQ(0, my_completion->get_return_value());
2397
2398 char buf2[64];
2399 memset(buf2, 0xdd, sizeof(buf2));
2400 bufferlist bl2;
2401 bl2.append(buf2, sizeof(buf2));
2402 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
2403 (void*)&test_data, set_completion_complete, set_completion_safe);
2404 ASSERT_NE(my_completion2, my_completion_null);
2405 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion2,
2406 bl2, sizeof(buf2), sizeof(buf)));
2407 {
2408 TestAlarm alarm;
2409 ASSERT_EQ(0, my_completion2->wait_for_complete());
2410 }
2411 ASSERT_EQ(0, my_completion2->get_return_value());
2412
2413 bufferlist bl3;
2414 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
2415 (void*)&test_data, set_completion_complete, set_completion_safe);
2416 ASSERT_NE(my_completion3, my_completion_null);
2417 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion3,
2418 &bl3, (sizeof(buf) + sizeof(buf2) * 3), 0));
2419 {
2420 TestAlarm alarm;
2421 ASSERT_EQ(0, my_completion3->wait_for_complete());
2422 }
2423 ASSERT_EQ((int)(sizeof(buf) + sizeof(buf2)), my_completion3->get_return_value());
2424 ASSERT_EQ(sizeof(buf) + sizeof(buf2), bl3.length());
2425 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
2426 ASSERT_EQ(0, memcmp(bl3.c_str() + sizeof(buf), buf2, sizeof(buf2)));
2427 delete my_completion;
2428 delete my_completion2;
2429 delete my_completion3;
2430 }
2431
2432 TEST(LibRadosAio, AioUnlock) {
2433 AioTestData test_data;
2434 ASSERT_EQ("", test_data.init());
2435 ASSERT_EQ(0, rados_lock_exclusive(test_data.m_ioctx, "foo", "TestLock", "Cookie", "", NULL, 0));
2436 rados_completion_t my_completion;
2437 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2438 set_completion_complete, set_completion_safe, &my_completion));
2439 ASSERT_EQ(0, rados_aio_unlock(test_data.m_ioctx, "foo", "TestLock", "Cookie", my_completion));
2440 {
2441 TestAlarm alarm;
2442 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
2443 }
2444 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
2445 ASSERT_EQ(0, rados_lock_exclusive(test_data.m_ioctx, "foo", "TestLock", "Cookie", "", NULL, 0));
2446 }
2447
2448 TEST(LibRadosAio, AioUnlockPP) {
2449 AioTestDataPP test_data;
2450 ASSERT_EQ("", test_data.init());
2451 ASSERT_EQ(0, test_data.m_ioctx.lock_exclusive("foo", "TestLock", "Cookie", "", NULL, 0));
2452 boost::scoped_ptr<AioCompletion> my_completion
2453 (test_data.m_cluster.aio_create_completion
2454 ((void*)&test_data, set_completion_completePP, set_completion_safePP));
2455 ASSERT_EQ(0, test_data.m_ioctx.aio_unlock("foo", "TestLock", "Cookie", my_completion.get()));
2456 {
2457 TestAlarm alarm;
2458 ASSERT_EQ(0, my_completion->wait_for_complete());
2459 }
2460 ASSERT_EQ(0, my_completion->get_return_value());
2461 bufferlist bl2;
2462 ASSERT_EQ(0, test_data.m_ioctx.lock_exclusive("foo", "TestLock", "Cookie", "", NULL, 0));
2463 }
2464
2465 // EC test cases
2466 class AioTestDataEC
2467 {
2468 public:
2469 AioTestDataEC()
2470 : m_cluster(NULL),
2471 m_ioctx(NULL),
2472 m_init(false),
2473 m_complete(false),
2474 m_safe(false)
2475 {
2476 }
2477
2478 ~AioTestDataEC()
2479 {
2480 if (m_init) {
2481 rados_ioctx_destroy(m_ioctx);
2482 destroy_one_ec_pool(m_pool_name, &m_cluster);
2483 sem_close(m_sem);
2484 }
2485 }
2486
2487 std::string init()
2488 {
2489 int ret;
2490 if (SEM_FAILED == (m_sem = sem_open("/test_aio_sem", O_CREAT, 0644, 0))) {
2491 int err = errno;
2492 ostringstream oss;
2493 oss << "sem_open failed: " << cpp_strerror(err);
2494 return oss.str();
2495 }
2496 m_pool_name = get_temp_pool_name();
2497 std::string err = create_one_ec_pool(m_pool_name, &m_cluster);
2498 if (!err.empty()) {
2499 sem_close(m_sem);
2500 ostringstream oss;
2501 oss << "create_one_ec_pool(" << m_pool_name << ") failed: error " << err;
2502 return oss.str();
2503 }
2504 ret = rados_ioctx_create(m_cluster, m_pool_name.c_str(), &m_ioctx);
2505 if (ret) {
2506 sem_close(m_sem);
2507 destroy_one_ec_pool(m_pool_name, &m_cluster);
2508 ostringstream oss;
2509 oss << "rados_ioctx_create failed: error " << ret;
2510 return oss.str();
2511 }
2512 m_init = true;
2513 return "";
2514 }
2515
2516 sem_t *m_sem;
2517 rados_t m_cluster;
2518 rados_ioctx_t m_ioctx;
2519 std::string m_pool_name;
2520 bool m_init;
2521 bool m_complete;
2522 bool m_safe;
2523 };
2524
2525 class AioTestDataECPP
2526 {
2527 public:
2528 AioTestDataECPP()
2529 : m_init(false),
2530 m_complete(false),
2531 m_safe(false)
2532 {
2533 }
2534
2535 ~AioTestDataECPP()
2536 {
2537 if (m_init) {
2538 m_ioctx.close();
2539 destroy_one_ec_pool_pp(m_pool_name, m_cluster);
2540 sem_close(m_sem);
2541 }
2542 }
2543
2544 std::string init()
2545 {
2546 int ret;
2547 if (SEM_FAILED == (m_sem = sem_open("/test_aio_sem", O_CREAT, 0644, 0))) {
2548 int err = errno;
2549 ostringstream oss;
2550 oss << "sem_open failed: " << cpp_strerror(err);
2551 return oss.str();
2552 }
2553 m_pool_name = get_temp_pool_name();
2554 std::string err = create_one_ec_pool_pp(m_pool_name, m_cluster);
2555 if (!err.empty()) {
2556 sem_close(m_sem);
2557 ostringstream oss;
2558 oss << "create_one_ec_pool(" << m_pool_name << ") failed: error " << err;
2559 return oss.str();
2560 }
2561 ret = m_cluster.ioctx_create(m_pool_name.c_str(), m_ioctx);
2562 if (ret) {
2563 sem_close(m_sem);
2564 destroy_one_ec_pool_pp(m_pool_name, m_cluster);
2565 ostringstream oss;
2566 oss << "rados_ioctx_create failed: error " << ret;
2567 return oss.str();
2568 }
2569 m_init = true;
2570 return "";
2571 }
2572
2573 sem_t *m_sem;
2574 Rados m_cluster;
2575 IoCtx m_ioctx;
2576 std::string m_pool_name;
2577 bool m_init;
2578 bool m_complete;
2579 bool m_safe;
2580 };
2581
2582 void set_completion_completeEC(rados_completion_t cb, void *arg)
2583 {
2584 AioTestDataEC *test = static_cast<AioTestDataEC*>(arg);
2585 test->m_complete = true;
2586 sem_post(test->m_sem);
2587 }
2588
2589 void set_completion_safeEC(rados_completion_t cb, void *arg)
2590 {
2591 AioTestDataEC *test = static_cast<AioTestDataEC*>(arg);
2592 test->m_safe = true;
2593 sem_post(test->m_sem);
2594 }
2595
2596 void set_completion_completeECPP(rados_completion_t cb, void *arg)
2597 {
2598 AioTestDataECPP *test = static_cast<AioTestDataECPP*>(arg);
2599 test->m_complete = true;
2600 sem_post(test->m_sem);
2601 }
2602
2603 void set_completion_safeECPP(rados_completion_t cb, void *arg)
2604 {
2605 AioTestDataECPP *test = static_cast<AioTestDataECPP*>(arg);
2606 test->m_safe = true;
2607 sem_post(test->m_sem);
2608 }
2609
2610 TEST(LibRadosAioEC, SimpleWrite) {
2611 AioTestDataEC test_data;
2612 rados_completion_t my_completion;
2613 ASSERT_EQ("", test_data.init());
2614 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2615 set_completion_completeEC, set_completion_safeEC, &my_completion));
2616 char buf[128];
2617 memset(buf, 0xcc, sizeof(buf));
2618 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
2619 my_completion, buf, sizeof(buf), 0));
2620 {
2621 TestAlarm alarm;
2622 sem_wait(test_data.m_sem);
2623 sem_wait(test_data.m_sem);
2624 }
2625 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
2626
2627 rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
2628 rados_completion_t my_completion2;
2629 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2630 set_completion_completeEC, set_completion_safeEC, &my_completion2));
2631 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
2632 my_completion2, buf, sizeof(buf), 0));
2633 {
2634 TestAlarm alarm;
2635 sem_wait(test_data.m_sem);
2636 sem_wait(test_data.m_sem);
2637 }
2638 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
2639 rados_aio_release(my_completion);
2640 rados_aio_release(my_completion2);
2641 }
2642
2643 TEST(LibRadosAioEC, SimpleWritePP) {
2644 char buf[128];
2645 memset(buf, 0xcc, sizeof(buf));
2646 bufferlist bl1;
2647 bl1.append(buf, sizeof(buf));
2648 {
2649 AioTestDataECPP test_data;
2650 ASSERT_EQ("", test_data.init());
2651 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2652 (void*)&test_data, set_completion_completeECPP, set_completion_safeECPP);
2653 AioCompletion *my_completion_null = NULL;
2654 ASSERT_NE(my_completion, my_completion_null);
2655 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
2656 my_completion, bl1, sizeof(buf), 0));
2657 {
2658 TestAlarm alarm;
2659 sem_wait(test_data.m_sem);
2660 sem_wait(test_data.m_sem);
2661 }
2662 ASSERT_EQ(0, my_completion->get_return_value());
2663 delete my_completion;
2664 }
2665
2666 {
2667 AioTestDataECPP test_data;
2668 ASSERT_EQ("", test_data.init());
2669 test_data.m_ioctx.set_namespace("nspace");
2670 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2671 (void*)&test_data, set_completion_completeECPP, set_completion_safeECPP);
2672 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
2673 my_completion, bl1, sizeof(buf), 0));
2674 {
2675 TestAlarm alarm;
2676 sem_wait(test_data.m_sem);
2677 sem_wait(test_data.m_sem);
2678 }
2679 ASSERT_EQ(0, my_completion->get_return_value());
2680 delete my_completion;
2681 }
2682 }
2683
2684 TEST(LibRadosAioEC, WaitForSafe) {
2685 AioTestDataEC test_data;
2686 rados_completion_t my_completion;
2687 ASSERT_EQ("", test_data.init());
2688 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2689 set_completion_completeEC, set_completion_safeEC, &my_completion));
2690 char buf[128];
2691 memset(buf, 0xcc, sizeof(buf));
2692 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
2693 my_completion, buf, sizeof(buf), 0));
2694 TestAlarm alarm;
2695 ASSERT_EQ(0, rados_aio_wait_for_safe(my_completion));
2696 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
2697 rados_aio_release(my_completion);
2698 }
2699
2700 TEST(LibRadosAioEC, WaitForSafePP) {
2701 AioTestDataECPP test_data;
2702 ASSERT_EQ("", test_data.init());
2703 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2704 (void*)&test_data, set_completion_completeECPP, set_completion_safeECPP);
2705 AioCompletion *my_completion_null = NULL;
2706 ASSERT_NE(my_completion, my_completion_null);
2707 char buf[128];
2708 memset(buf, 0xcc, sizeof(buf));
2709 bufferlist bl1;
2710 bl1.append(buf, sizeof(buf));
2711 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
2712 my_completion, bl1, sizeof(buf), 0));
2713 TestAlarm alarm;
2714 ASSERT_EQ(0, my_completion->wait_for_safe());
2715 ASSERT_EQ(0, my_completion->get_return_value());
2716 delete my_completion;
2717 }
2718
2719 TEST(LibRadosAioEC, RoundTrip) {
2720 AioTestDataEC test_data;
2721 rados_completion_t my_completion;
2722 ASSERT_EQ("", test_data.init());
2723 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2724 set_completion_completeEC, set_completion_safeEC, &my_completion));
2725 char buf[128];
2726 memset(buf, 0xcc, sizeof(buf));
2727 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
2728 my_completion, buf, sizeof(buf), 0));
2729 {
2730 TestAlarm alarm;
2731 sem_wait(test_data.m_sem);
2732 sem_wait(test_data.m_sem);
2733 }
2734 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
2735 char buf2[256];
2736 memset(buf2, 0, sizeof(buf2));
2737 rados_completion_t my_completion2;
2738 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2739 set_completion_completeEC, set_completion_safeEC, &my_completion2));
2740 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
2741 my_completion2, buf2, sizeof(buf2), 0));
2742 {
2743 TestAlarm alarm;
2744 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
2745 }
2746 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
2747 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
2748 rados_aio_release(my_completion);
2749 rados_aio_release(my_completion2);
2750 }
2751
2752 TEST(LibRadosAioEC, RoundTrip2) {
2753 AioTestDataEC test_data;
2754 rados_completion_t my_completion;
2755 ASSERT_EQ("", test_data.init());
2756 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2757 set_completion_completeEC, set_completion_safeEC, &my_completion));
2758 char buf[128];
2759 memset(buf, 0xcc, sizeof(buf));
2760 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
2761 my_completion, buf, sizeof(buf), 0));
2762 {
2763 TestAlarm alarm;
2764 sem_wait(test_data.m_sem);
2765 sem_wait(test_data.m_sem);
2766 }
2767 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
2768 char buf2[128];
2769 memset(buf2, 0, sizeof(buf2));
2770 rados_completion_t my_completion2;
2771 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2772 set_completion_completeEC, set_completion_safeEC, &my_completion2));
2773 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
2774 my_completion2, buf2, sizeof(buf2), 0));
2775 {
2776 TestAlarm alarm;
2777 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
2778 }
2779 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
2780 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
2781 rados_aio_release(my_completion);
2782 rados_aio_release(my_completion2);
2783 }
2784
2785 TEST(LibRadosAioEC, RoundTripPP) {
2786 AioTestDataECPP test_data;
2787 ASSERT_EQ("", test_data.init());
2788 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2789 (void*)&test_data, set_completion_completeECPP, set_completion_safeECPP);
2790 AioCompletion *my_completion_null = NULL;
2791 ASSERT_NE(my_completion, my_completion_null);
2792 char buf[128];
2793 memset(buf, 0xcc, sizeof(buf));
2794 bufferlist bl1;
2795 bl1.append(buf, sizeof(buf));
2796 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
2797 bl1, sizeof(buf), 0));
2798 {
2799 TestAlarm alarm;
2800 sem_wait(test_data.m_sem);
2801 sem_wait(test_data.m_sem);
2802 }
2803 ASSERT_EQ(0, my_completion->get_return_value());
2804 bufferlist bl2;
2805 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
2806 (void*)&test_data, set_completion_completeECPP, set_completion_safeECPP);
2807 ASSERT_NE(my_completion2, my_completion_null);
2808 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo",
2809 my_completion2, &bl2, sizeof(buf), 0));
2810 {
2811 TestAlarm alarm;
2812 ASSERT_EQ(0, my_completion2->wait_for_complete());
2813 }
2814 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
2815 ASSERT_EQ(sizeof(buf), bl2.length());
2816 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
2817 delete my_completion;
2818 delete my_completion2;
2819 }
2820
2821 TEST(LibRadosAioEC, RoundTripPP2) {
2822 AioTestDataECPP test_data;
2823 ASSERT_EQ("", test_data.init());
2824 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2825 (void*)&test_data, set_completion_completeECPP, set_completion_safeECPP);
2826 AioCompletion *my_completion_null = NULL;
2827 ASSERT_NE(my_completion, my_completion_null);
2828 char buf[128];
2829 memset(buf, 0xcc, sizeof(buf));
2830 bufferlist bl1;
2831 bl1.append(buf, sizeof(buf));
2832 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
2833 bl1, sizeof(buf), 0));
2834 {
2835 TestAlarm alarm;
2836 sem_wait(test_data.m_sem);
2837 sem_wait(test_data.m_sem);
2838 }
2839 ASSERT_EQ(0, my_completion->get_return_value());
2840 bufferlist bl2;
2841 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
2842 (void*)&test_data, set_completion_completeECPP, set_completion_safeECPP);
2843 ASSERT_NE(my_completion2, my_completion_null);
2844 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo",
2845 my_completion2, &bl2, sizeof(buf), 0));
2846 {
2847 TestAlarm alarm;
2848 ASSERT_EQ(0, my_completion2->wait_for_safe());
2849 ASSERT_EQ(0, my_completion2->wait_for_complete());
2850 }
2851 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
2852 ASSERT_EQ(sizeof(buf), bl2.length());
2853 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
2854 delete my_completion;
2855 delete my_completion2;
2856 }
2857
2858 //using ObjectWriteOperation/ObjectReadOperation with iohint
2859 TEST(LibRadosAioEC, RoundTripPP3)
2860 {
2861 Rados cluster;
2862 std::string pool_name = get_temp_pool_name();
2863 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
2864 IoCtx ioctx;
2865 cluster.ioctx_create(pool_name.c_str(), ioctx);
2866
2867 boost::scoped_ptr<AioCompletion> my_completion1(cluster.aio_create_completion(0, 0, 0));
2868 ObjectWriteOperation op;
2869 char buf[128];
2870 memset(buf, 0xcc, sizeof(buf));
2871 bufferlist bl;
2872 bl.append(buf);
2873
2874 op.write(0, bl);
2875 op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
2876 ioctx.aio_operate("test_obj", my_completion1.get(), &op);
2877 {
2878 TestAlarm alarm;
2879 ASSERT_EQ(0, my_completion1->wait_for_complete());
2880 }
2881 EXPECT_EQ(0, my_completion1->get_return_value());
2882
2883 boost::scoped_ptr<AioCompletion> my_completion2(cluster.aio_create_completion(0, 0, 0));
2884 bl.clear();
2885 ObjectReadOperation op1;
2886 op1.read(0, sizeof(buf), &bl, NULL);
2887 op1.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED|LIBRADOS_OP_FLAG_FADVISE_RANDOM);
2888 ioctx.aio_operate("test_obj", my_completion2.get(), &op1, 0);
2889 {
2890 TestAlarm alarm;
2891 ASSERT_EQ(0, my_completion2->wait_for_complete());
2892 }
2893 EXPECT_EQ(0, my_completion2->get_return_value());
2894 ASSERT_EQ(0, memcmp(buf, bl.c_str(), sizeof(buf)));
2895
2896 ioctx.remove("test_obj");
2897 destroy_one_pool_pp(pool_name, cluster);
2898 }
2899
2900 TEST(LibRadosAioEC, RoundTripSparseReadPP) {
2901 AioTestDataECPP test_data;
2902 ASSERT_EQ("", test_data.init());
2903 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2904 (void*)&test_data, set_completion_completeECPP, set_completion_safeECPP);
2905 AioCompletion *my_completion_null = NULL;
2906 ASSERT_NE(my_completion, my_completion_null);
2907 char buf[128];
2908 memset(buf, 0xcc, sizeof(buf));
2909 bufferlist bl1;
2910 bl1.append(buf, sizeof(buf));
2911 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
2912 bl1, sizeof(buf), 0));
2913 {
2914 TestAlarm alarm;
2915 sem_wait(test_data.m_sem);
2916 sem_wait(test_data.m_sem);
2917 }
2918 ASSERT_EQ(0, my_completion->get_return_value());
2919
2920 map<uint64_t, uint64_t> extents;
2921 bufferlist bl2;
2922 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
2923 (void*)&test_data, set_completion_completeECPP, set_completion_safeECPP);
2924 ASSERT_NE(my_completion2, my_completion_null);
2925 ASSERT_EQ(0, test_data.m_ioctx.aio_sparse_read("foo",
2926 my_completion2, &extents, &bl2, sizeof(buf), 0));
2927 {
2928 TestAlarm alarm;
2929 ASSERT_EQ(0, my_completion2->wait_for_complete());
2930 }
2931 ASSERT_EQ(0, my_completion2->get_return_value());
2932 assert_eq_sparse(bl1, extents, bl2);
2933 delete my_completion;
2934 delete my_completion2;
2935 }
2936
2937 TEST(LibRadosAioEC, RoundTripAppend) {
2938 AioTestDataEC test_data;
2939 rados_completion_t my_completion, my_completion2, my_completion3, my_completion4;
2940 ASSERT_EQ("", test_data.init());
2941 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2942 set_completion_completeEC, set_completion_safeEC, &my_completion));
2943 int requires;
2944 ASSERT_EQ(0, rados_ioctx_pool_requires_alignment2(test_data.m_ioctx, &requires));
2945 ASSERT_NE(0, requires);
2946 uint64_t alignment;
2947 ASSERT_EQ(0, rados_ioctx_pool_required_alignment2(test_data.m_ioctx, &alignment));
2948 ASSERT_NE(0U, alignment);
2949
2950 int bsize = alignment;
2951 char *buf = (char *)new char[bsize];
2952 memset(buf, 0xcc, bsize);
2953 ASSERT_EQ(0, rados_aio_append(test_data.m_ioctx, "foo",
2954 my_completion, buf, bsize));
2955 {
2956 TestAlarm alarm;
2957 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
2958 }
2959 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
2960
2961 int hbsize = bsize / 2;
2962 char *buf2 = (char *)new char[hbsize];
2963 memset(buf2, 0xdd, hbsize);
2964 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2965 set_completion_completeEC, set_completion_safeEC, &my_completion2));
2966 ASSERT_EQ(0, rados_aio_append(test_data.m_ioctx, "foo",
2967 my_completion2, buf2, hbsize));
2968 {
2969 TestAlarm alarm;
2970 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
2971 }
2972 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
2973
2974 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2975 set_completion_completeEC, set_completion_safeEC, &my_completion3));
2976 ASSERT_EQ(0, rados_aio_append(test_data.m_ioctx, "foo",
2977 my_completion3, buf2, hbsize));
2978 {
2979 TestAlarm alarm;
2980 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
2981 }
2982 EXPECT_EQ(-EOPNOTSUPP, rados_aio_get_return_value(my_completion3));
2983
2984 int tbsize = bsize + hbsize;
2985 char *buf3 = (char *)new char[tbsize];
2986 memset(buf3, 0, tbsize);
2987 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
2988 set_completion_completeEC, set_completion_safeEC, &my_completion4));
2989 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
2990 my_completion4, buf3, bsize * 3, 0));
2991 {
2992 TestAlarm alarm;
2993 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4));
2994 }
2995 ASSERT_EQ(tbsize, rados_aio_get_return_value(my_completion4));
2996 ASSERT_EQ(0, memcmp(buf3, buf, bsize));
2997 ASSERT_EQ(0, memcmp(buf3 + bsize, buf2, hbsize));
2998 rados_aio_release(my_completion);
2999 rados_aio_release(my_completion2);
3000 rados_aio_release(my_completion3);
3001 rados_aio_release(my_completion4);
3002 delete[] buf;
3003 delete[] buf2;
3004 delete[] buf3;
3005 }
3006
3007 TEST(LibRadosAioEC, RoundTripAppendPP) {
3008 AioTestDataECPP test_data;
3009 ASSERT_EQ("", test_data.init());
3010 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
3011 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3012 AioCompletion *my_completion_null = NULL;
3013 ASSERT_NE(my_completion, my_completion_null);
3014 bool requires;
3015 ASSERT_EQ(0, test_data.m_ioctx.pool_requires_alignment2(&requires));
3016 ASSERT_TRUE(requires);
3017 uint64_t alignment;
3018 ASSERT_EQ(0, test_data.m_ioctx.pool_required_alignment2(&alignment));
3019 ASSERT_NE((unsigned)0, alignment);
3020 int bsize = alignment;
3021 char *buf = (char *)new char[bsize];
3022 memset(buf, 0xcc, bsize);
3023 bufferlist bl1;
3024 bl1.append(buf, bsize);
3025 ASSERT_EQ(0, test_data.m_ioctx.aio_append("foo", my_completion,
3026 bl1, bsize));
3027 {
3028 TestAlarm alarm;
3029 ASSERT_EQ(0, my_completion->wait_for_complete());
3030 }
3031 ASSERT_EQ(0, my_completion->get_return_value());
3032
3033 int hbsize = bsize / 2;
3034 char *buf2 = (char *)new char[hbsize];
3035 memset(buf2, 0xdd, hbsize);
3036 bufferlist bl2;
3037 bl2.append(buf2, hbsize);
3038 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
3039 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3040 ASSERT_NE(my_completion2, my_completion_null);
3041 ASSERT_EQ(0, test_data.m_ioctx.aio_append("foo", my_completion2,
3042 bl2, hbsize));
3043 {
3044 TestAlarm alarm;
3045 ASSERT_EQ(0, my_completion2->wait_for_complete());
3046 }
3047 ASSERT_EQ(0, my_completion2->get_return_value());
3048
3049 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
3050 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3051 ASSERT_NE(my_completion3, my_completion_null);
3052 ASSERT_EQ(0, test_data.m_ioctx.aio_append("foo", my_completion3,
3053 bl2, hbsize));
3054 {
3055 TestAlarm alarm;
3056 ASSERT_EQ(0, my_completion3->wait_for_complete());
3057 }
3058 EXPECT_EQ(-EOPNOTSUPP, my_completion3->get_return_value());
3059
3060 bufferlist bl3;
3061 AioCompletion *my_completion4 = test_data.m_cluster.aio_create_completion(
3062 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3063 ASSERT_NE(my_completion4, my_completion_null);
3064 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo",
3065 my_completion4, &bl3, bsize * 3, 0));
3066 {
3067 TestAlarm alarm;
3068 ASSERT_EQ(0, my_completion4->wait_for_complete());
3069 }
3070 int tbsize = bsize + hbsize;
3071 ASSERT_EQ(tbsize, my_completion4->get_return_value());
3072 ASSERT_EQ((unsigned)tbsize, bl3.length());
3073 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, bsize));
3074 ASSERT_EQ(0, memcmp(bl3.c_str() + bsize, buf2, hbsize));
3075 delete my_completion;
3076 delete my_completion2;
3077 delete my_completion3;
3078 delete[] buf;
3079 delete[] buf2;
3080 }
3081
3082 TEST(LibRadosAioEC, IsComplete) {
3083 AioTestDataEC test_data;
3084 rados_completion_t my_completion;
3085 ASSERT_EQ("", test_data.init());
3086 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3087 set_completion_completeEC, set_completion_safeEC, &my_completion));
3088 char buf[128];
3089 memset(buf, 0xcc, sizeof(buf));
3090 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
3091 my_completion, buf, sizeof(buf), 0));
3092 {
3093 TestAlarm alarm;
3094 sem_wait(test_data.m_sem);
3095 sem_wait(test_data.m_sem);
3096 }
3097 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
3098 char buf2[128];
3099 memset(buf2, 0, sizeof(buf2));
3100 rados_completion_t my_completion2;
3101 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3102 set_completion_completeEC, set_completion_safeEC, &my_completion2));
3103 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
3104 my_completion2, buf2, sizeof(buf2), 0));
3105 {
3106 TestAlarm alarm;
3107
3108 // Busy-wait until the AIO completes.
3109 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
3110 while (true) {
3111 int is_complete = rados_aio_is_complete(my_completion2);
3112 if (is_complete)
3113 break;
3114 }
3115 }
3116 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
3117 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
3118 rados_aio_release(my_completion);
3119 rados_aio_release(my_completion2);
3120 }
3121
3122 TEST(LibRadosAioEC, IsCompletePP) {
3123 AioTestDataECPP test_data;
3124 ASSERT_EQ("", test_data.init());
3125 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
3126 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3127 AioCompletion *my_completion_null = NULL;
3128 ASSERT_NE(my_completion, my_completion_null);
3129 char buf[128];
3130 memset(buf, 0xcc, sizeof(buf));
3131 bufferlist bl1;
3132 bl1.append(buf, sizeof(buf));
3133 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
3134 bl1, sizeof(buf), 0));
3135 {
3136 TestAlarm alarm;
3137 sem_wait(test_data.m_sem);
3138 sem_wait(test_data.m_sem);
3139 }
3140 ASSERT_EQ(0, my_completion->get_return_value());
3141 bufferlist bl2;
3142 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
3143 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3144 ASSERT_NE(my_completion2, my_completion_null);
3145 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
3146 &bl2, sizeof(buf), 0));
3147 {
3148 TestAlarm alarm;
3149
3150 // Busy-wait until the AIO completes.
3151 // Normally we wouldn't do this, but we want to test is_complete.
3152 while (true) {
3153 int is_complete = my_completion2->is_complete();
3154 if (is_complete)
3155 break;
3156 }
3157 }
3158 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
3159 ASSERT_EQ(sizeof(buf), bl2.length());
3160 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
3161 delete my_completion;
3162 delete my_completion2;
3163 }
3164
3165 TEST(LibRadosAioEC, IsSafe) {
3166 AioTestDataEC test_data;
3167 rados_completion_t my_completion;
3168 ASSERT_EQ("", test_data.init());
3169 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3170 set_completion_completeEC, set_completion_safeEC, &my_completion));
3171 char buf[128];
3172 memset(buf, 0xcc, sizeof(buf));
3173 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
3174 my_completion, buf, sizeof(buf), 0));
3175 {
3176 TestAlarm alarm;
3177
3178 // Busy-wait until the AIO completes.
3179 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
3180 while (true) {
3181 int is_safe = rados_aio_is_safe(my_completion);
3182 if (is_safe)
3183 break;
3184 }
3185 }
3186 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
3187 char buf2[128];
3188 memset(buf2, 0, sizeof(buf2));
3189 rados_completion_t my_completion2;
3190 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3191 set_completion_completeEC, set_completion_safeEC, &my_completion2));
3192 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
3193 my_completion2, buf2, sizeof(buf2), 0));
3194 {
3195 TestAlarm alarm;
3196 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
3197 }
3198 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
3199 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
3200 rados_aio_release(my_completion);
3201 rados_aio_release(my_completion2);
3202 }
3203
3204 TEST(LibRadosAioEC, IsSafePP) {
3205 AioTestDataECPP test_data;
3206 ASSERT_EQ("", test_data.init());
3207 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
3208 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3209 AioCompletion *my_completion_null = NULL;
3210 ASSERT_NE(my_completion, my_completion_null);
3211 char buf[128];
3212 memset(buf, 0xcc, sizeof(buf));
3213 bufferlist bl1;
3214 bl1.append(buf, sizeof(buf));
3215 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
3216 bl1, sizeof(buf), 0));
3217 {
3218 TestAlarm alarm;
3219
3220 // Busy-wait until the AIO completes.
3221 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
3222 while (true) {
3223 int is_safe = my_completion->is_safe();
3224 if (is_safe)
3225 break;
3226 }
3227 }
3228 ASSERT_EQ(0, my_completion->get_return_value());
3229 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
3230 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3231 bufferlist bl2;
3232 ASSERT_NE(my_completion2, my_completion_null);
3233 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
3234 &bl2, sizeof(buf), 0));
3235 {
3236 TestAlarm alarm;
3237 ASSERT_EQ(0, my_completion2->wait_for_complete());
3238 }
3239 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
3240 ASSERT_EQ(sizeof(buf), bl2.length());
3241 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
3242 delete my_completion;
3243 delete my_completion2;
3244 }
3245
3246 TEST(LibRadosAioEC, ReturnValue) {
3247 AioTestDataEC test_data;
3248 rados_completion_t my_completion;
3249 ASSERT_EQ("", test_data.init());
3250 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3251 set_completion_completeEC, set_completion_safeEC, &my_completion));
3252 char buf[128];
3253 memset(buf, 0, sizeof(buf));
3254 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "nonexistent",
3255 my_completion, buf, sizeof(buf), 0));
3256 {
3257 TestAlarm alarm;
3258 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
3259 }
3260 ASSERT_EQ(-ENOENT, rados_aio_get_return_value(my_completion));
3261 rados_aio_release(my_completion);
3262 }
3263
3264 TEST(LibRadosAioEC, ReturnValuePP) {
3265 AioTestDataECPP test_data;
3266 ASSERT_EQ("", test_data.init());
3267 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
3268 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3269 AioCompletion *my_completion_null = NULL;
3270 ASSERT_NE(my_completion, my_completion_null);
3271 bufferlist bl1;
3272 ASSERT_EQ(0, test_data.m_ioctx.aio_read("nonexistent",
3273 my_completion, &bl1, 128, 0));
3274 {
3275 TestAlarm alarm;
3276 ASSERT_EQ(0, my_completion->wait_for_complete());
3277 }
3278 ASSERT_EQ(-ENOENT, my_completion->get_return_value());
3279 delete my_completion;
3280 }
3281
3282 TEST(LibRadosAioEC, Flush) {
3283 AioTestDataEC test_data;
3284 rados_completion_t my_completion;
3285 ASSERT_EQ("", test_data.init());
3286 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3287 set_completion_completeEC, set_completion_safeEC, &my_completion));
3288 char buf[128];
3289 memset(buf, 0xee, sizeof(buf));
3290 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
3291 my_completion, buf, sizeof(buf), 0));
3292 ASSERT_EQ(0, rados_aio_flush(test_data.m_ioctx));
3293 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
3294 char buf2[128];
3295 memset(buf2, 0, sizeof(buf2));
3296 rados_completion_t my_completion2;
3297 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3298 set_completion_completeEC, set_completion_safeEC, &my_completion2));
3299 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
3300 my_completion2, buf2, sizeof(buf2), 0));
3301 {
3302 TestAlarm alarm;
3303 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
3304 }
3305 ASSERT_EQ((int)sizeof(buf2), rados_aio_get_return_value(my_completion2));
3306 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
3307 rados_aio_release(my_completion);
3308 rados_aio_release(my_completion2);
3309 }
3310
3311 TEST(LibRadosAioEC, FlushPP) {
3312 AioTestDataECPP test_data;
3313 ASSERT_EQ("", test_data.init());
3314 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
3315 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3316 AioCompletion *my_completion_null = NULL;
3317 ASSERT_NE(my_completion, my_completion_null);
3318 char buf[128];
3319 memset(buf, 0xee, sizeof(buf));
3320 bufferlist bl1;
3321 bl1.append(buf, sizeof(buf));
3322 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
3323 bl1, sizeof(buf), 0));
3324 ASSERT_EQ(0, test_data.m_ioctx.aio_flush());
3325 ASSERT_EQ(0, my_completion->get_return_value());
3326 bufferlist bl2;
3327 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
3328 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3329 ASSERT_NE(my_completion2, my_completion_null);
3330 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
3331 &bl2, sizeof(buf), 0));
3332 {
3333 TestAlarm alarm;
3334 ASSERT_EQ(0, my_completion2->wait_for_complete());
3335 }
3336 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
3337 ASSERT_EQ(sizeof(buf), bl2.length());
3338 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
3339 delete my_completion;
3340 delete my_completion2;
3341 }
3342
3343 TEST(LibRadosAioEC, FlushAsync) {
3344 AioTestDataEC test_data;
3345 rados_completion_t my_completion;
3346 ASSERT_EQ("", test_data.init());
3347 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3348 set_completion_completeEC, set_completion_safeEC, &my_completion));
3349 rados_completion_t flush_completion;
3350 ASSERT_EQ(0, rados_aio_create_completion(NULL, NULL, NULL, &flush_completion));
3351 char buf[128];
3352 memset(buf, 0xee, sizeof(buf));
3353 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
3354 my_completion, buf, sizeof(buf), 0));
3355 ASSERT_EQ(0, rados_aio_flush_async(test_data.m_ioctx, flush_completion));
3356 {
3357 TestAlarm alarm;
3358 ASSERT_EQ(0, rados_aio_wait_for_complete(flush_completion));
3359 ASSERT_EQ(0, rados_aio_wait_for_safe(flush_completion));
3360 }
3361 ASSERT_EQ(1, rados_aio_is_complete(my_completion));
3362 ASSERT_EQ(1, rados_aio_is_safe(my_completion));
3363 ASSERT_EQ(1, rados_aio_is_complete(flush_completion));
3364 ASSERT_EQ(1, rados_aio_is_safe(flush_completion));
3365 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
3366 char buf2[128];
3367 memset(buf2, 0, sizeof(buf2));
3368 rados_completion_t my_completion2;
3369 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3370 set_completion_completeEC, set_completion_safeEC, &my_completion2));
3371 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
3372 my_completion2, buf2, sizeof(buf2), 0));
3373 {
3374 TestAlarm alarm;
3375 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
3376 }
3377 ASSERT_EQ((int)sizeof(buf2), rados_aio_get_return_value(my_completion2));
3378 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
3379 rados_aio_release(my_completion);
3380 rados_aio_release(my_completion2);
3381 rados_aio_release(flush_completion);
3382 }
3383
3384 TEST(LibRadosAioEC, FlushAsyncPP) {
3385 AioTestDataECPP test_data;
3386 ASSERT_EQ("", test_data.init());
3387 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
3388 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3389 AioCompletion *flush_completion =
3390 test_data.m_cluster.aio_create_completion(NULL, NULL, NULL);
3391 AioCompletion *my_completion_null = NULL;
3392 ASSERT_NE(my_completion, my_completion_null);
3393 char buf[128];
3394 memset(buf, 0xee, sizeof(buf));
3395 bufferlist bl1;
3396 bl1.append(buf, sizeof(buf));
3397 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
3398 bl1, sizeof(buf), 0));
3399 ASSERT_EQ(0, test_data.m_ioctx.aio_flush_async(flush_completion));
3400 {
3401 TestAlarm alarm;
3402 ASSERT_EQ(0, flush_completion->wait_for_complete());
3403 ASSERT_EQ(0, flush_completion->wait_for_safe());
3404 }
3405 ASSERT_EQ(1, my_completion->is_complete());
3406 ASSERT_EQ(1, my_completion->is_safe());
3407 ASSERT_EQ(1, flush_completion->is_complete());
3408 ASSERT_EQ(1, flush_completion->is_safe());
3409 ASSERT_EQ(0, my_completion->get_return_value());
3410 bufferlist bl2;
3411 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
3412 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3413 ASSERT_NE(my_completion2, my_completion_null);
3414 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
3415 &bl2, sizeof(buf), 0));
3416 {
3417 TestAlarm alarm;
3418 ASSERT_EQ(0, my_completion2->wait_for_complete());
3419 }
3420 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
3421 ASSERT_EQ(sizeof(buf), bl2.length());
3422 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
3423 delete my_completion;
3424 delete my_completion2;
3425 delete flush_completion;
3426 }
3427
3428 TEST(LibRadosAioEC, RoundTripWriteFull) {
3429 AioTestDataEC test_data;
3430 rados_completion_t my_completion, my_completion2, my_completion3;
3431 ASSERT_EQ("", test_data.init());
3432 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3433 set_completion_completeEC, set_completion_safeEC, &my_completion));
3434 char buf[128];
3435 memset(buf, 0xcc, sizeof(buf));
3436 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
3437 my_completion, buf, sizeof(buf), 0));
3438 {
3439 TestAlarm alarm;
3440 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
3441 }
3442 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
3443 char buf2[64];
3444 memset(buf2, 0xdd, sizeof(buf2));
3445 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3446 set_completion_completeEC, set_completion_safeEC, &my_completion2));
3447 ASSERT_EQ(0, rados_aio_write_full(test_data.m_ioctx, "foo",
3448 my_completion2, buf2, sizeof(buf2)));
3449 {
3450 TestAlarm alarm;
3451 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
3452 }
3453 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
3454 char buf3[sizeof(buf) + sizeof(buf2)];
3455 memset(buf3, 0, sizeof(buf3));
3456 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3457 set_completion_completeEC, set_completion_safeEC, &my_completion3));
3458 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
3459 my_completion3, buf3, sizeof(buf3), 0));
3460 {
3461 TestAlarm alarm;
3462 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
3463 }
3464 ASSERT_EQ((int)sizeof(buf2), rados_aio_get_return_value(my_completion3));
3465 ASSERT_EQ(0, memcmp(buf3, buf2, sizeof(buf2)));
3466 rados_aio_release(my_completion);
3467 rados_aio_release(my_completion2);
3468 rados_aio_release(my_completion3);
3469 }
3470
3471 TEST(LibRadosAioEC, RoundTripWriteFullPP) {
3472 AioTestDataECPP test_data;
3473 ASSERT_EQ("", test_data.init());
3474 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
3475 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3476 AioCompletion *my_completion_null = NULL;
3477 ASSERT_NE(my_completion, my_completion_null);
3478 char buf[128];
3479 memset(buf, 0xcc, sizeof(buf));
3480 bufferlist bl1;
3481 bl1.append(buf, sizeof(buf));
3482 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
3483 bl1, sizeof(buf), 0));
3484 {
3485 TestAlarm alarm;
3486 ASSERT_EQ(0, my_completion->wait_for_complete());
3487 }
3488 ASSERT_EQ(0, my_completion->get_return_value());
3489 char buf2[64];
3490 memset(buf2, 0xdd, sizeof(buf2));
3491 bufferlist bl2;
3492 bl2.append(buf2, sizeof(buf2));
3493 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
3494 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3495 ASSERT_NE(my_completion2, my_completion_null);
3496 ASSERT_EQ(0, test_data.m_ioctx.aio_write_full("foo", my_completion2, bl2));
3497 {
3498 TestAlarm alarm;
3499 ASSERT_EQ(0, my_completion2->wait_for_complete());
3500 }
3501 ASSERT_EQ(0, my_completion2->get_return_value());
3502 bufferlist bl3;
3503 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
3504 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3505 ASSERT_NE(my_completion3, my_completion_null);
3506 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion3,
3507 &bl3, sizeof(buf), 0));
3508 {
3509 TestAlarm alarm;
3510 ASSERT_EQ(0, my_completion3->wait_for_complete());
3511 }
3512 ASSERT_EQ((int)sizeof(buf2), my_completion3->get_return_value());
3513 ASSERT_EQ(sizeof(buf2), bl3.length());
3514 ASSERT_EQ(0, memcmp(bl3.c_str(), buf2, sizeof(buf2)));
3515 delete my_completion;
3516 delete my_completion2;
3517 delete my_completion3;
3518 }
3519
3520 //using ObjectWriteOperation/ObjectReadOperation with iohint
3521 TEST(LibRadosAioEC, RoundTripWriteFullPP2)
3522 {
3523 Rados cluster;
3524 std::string pool_name = get_temp_pool_name();
3525 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
3526 IoCtx ioctx;
3527 cluster.ioctx_create(pool_name.c_str(), ioctx);
3528
3529 boost::scoped_ptr<AioCompletion> my_completion1(cluster.aio_create_completion(0, 0, 0));
3530 ObjectWriteOperation op;
3531 char buf[128];
3532 memset(buf, 0xcc, sizeof(buf));
3533 bufferlist bl;
3534 bl.append(buf);
3535
3536 op.write_full(bl);
3537 op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE);
3538 ioctx.aio_operate("test_obj", my_completion1.get(), &op);
3539 {
3540 TestAlarm alarm;
3541 ASSERT_EQ(0, my_completion1->wait_for_complete());
3542 }
3543 EXPECT_EQ(0, my_completion1->get_return_value());
3544
3545 boost::scoped_ptr<AioCompletion> my_completion2(cluster.aio_create_completion(0, 0, 0));
3546 bl.clear();
3547 ObjectReadOperation op1;
3548 op1.read(0, sizeof(buf), &bl, NULL);
3549 op1.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE|LIBRADOS_OP_FLAG_FADVISE_RANDOM);
3550 ioctx.aio_operate("test_obj", my_completion2.get(), &op1, 0);
3551 {
3552 TestAlarm alarm;
3553 ASSERT_EQ(0, my_completion2->wait_for_complete());
3554 }
3555 EXPECT_EQ(0, my_completion2->get_return_value());
3556 ASSERT_EQ(0, memcmp(buf, bl.c_str(), sizeof(buf)));
3557
3558 ioctx.remove("test_obj");
3559 destroy_one_pool_pp(pool_name, cluster);
3560 }
3561
3562 TEST(LibRadosAioEC, SimpleStat) {
3563 AioTestDataEC test_data;
3564 rados_completion_t my_completion;
3565 ASSERT_EQ("", test_data.init());
3566 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3567 set_completion_completeEC, set_completion_safeEC, &my_completion));
3568 char buf[128];
3569 memset(buf, 0xcc, sizeof(buf));
3570 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
3571 my_completion, buf, sizeof(buf), 0));
3572 {
3573 TestAlarm alarm;
3574 sem_wait(test_data.m_sem);
3575 sem_wait(test_data.m_sem);
3576 }
3577 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
3578 uint64_t psize;
3579 time_t pmtime;
3580 rados_completion_t my_completion2;
3581 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3582 set_completion_completeEC, set_completion_safeEC, &my_completion2));
3583 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
3584 my_completion2, &psize, &pmtime));
3585 {
3586 TestAlarm alarm;
3587 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
3588 }
3589 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
3590 ASSERT_EQ(sizeof(buf), psize);
3591 rados_aio_release(my_completion);
3592 rados_aio_release(my_completion2);
3593 }
3594
3595 TEST(LibRadosAioEC, SimpleStatPP) {
3596 AioTestDataECPP test_data;
3597 ASSERT_EQ("", test_data.init());
3598 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
3599 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3600 AioCompletion *my_completion_null = NULL;
3601 ASSERT_NE(my_completion, my_completion_null);
3602 char buf[128];
3603 memset(buf, 0xcc, sizeof(buf));
3604 bufferlist bl1;
3605 bl1.append(buf, sizeof(buf));
3606 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
3607 bl1, sizeof(buf), 0));
3608 {
3609 TestAlarm alarm;
3610 sem_wait(test_data.m_sem);
3611 sem_wait(test_data.m_sem);
3612 }
3613 ASSERT_EQ(0, my_completion->get_return_value());
3614 uint64_t psize;
3615 time_t pmtime;
3616 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
3617 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3618 ASSERT_NE(my_completion2, my_completion_null);
3619 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion2,
3620 &psize, &pmtime));
3621 {
3622 TestAlarm alarm;
3623 ASSERT_EQ(0, my_completion2->wait_for_complete());
3624 }
3625 ASSERT_EQ(0, my_completion2->get_return_value());
3626 ASSERT_EQ(sizeof(buf), psize);
3627 delete my_completion;
3628 delete my_completion2;
3629 }
3630
3631 TEST(LibRadosAioEC, SimpleStatNS) {
3632 AioTestDataEC test_data;
3633 rados_completion_t my_completion;
3634 ASSERT_EQ("", test_data.init());
3635 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3636 set_completion_completeEC, set_completion_safeEC, &my_completion));
3637 char buf[128];
3638 memset(buf, 0xcc, sizeof(buf));
3639 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
3640 my_completion, buf, sizeof(buf), 0));
3641 {
3642 TestAlarm alarm;
3643 sem_wait(test_data.m_sem);
3644 sem_wait(test_data.m_sem);
3645 }
3646 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
3647 rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
3648 char buf2[64];
3649 memset(buf2, 0xbb, sizeof(buf2));
3650 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3651 set_completion_completeEC, set_completion_safeEC, &my_completion));
3652 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
3653 my_completion, buf2, sizeof(buf2), 0));
3654 {
3655 TestAlarm alarm;
3656 sem_wait(test_data.m_sem);
3657 sem_wait(test_data.m_sem);
3658 }
3659 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
3660 uint64_t psize;
3661 time_t pmtime;
3662 rados_completion_t my_completion2;
3663 rados_ioctx_set_namespace(test_data.m_ioctx, "");
3664 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3665 set_completion_completeEC, set_completion_safeEC, &my_completion2));
3666 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
3667 my_completion2, &psize, &pmtime));
3668 {
3669 TestAlarm alarm;
3670 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
3671 }
3672 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
3673 ASSERT_EQ(sizeof(buf), psize);
3674
3675 rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
3676 rados_completion_t my_completion3;
3677 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3678 set_completion_completeEC, set_completion_safeEC, &my_completion3));
3679 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
3680 my_completion3, &psize, &pmtime));
3681 {
3682 TestAlarm alarm;
3683 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
3684 }
3685 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3));
3686 ASSERT_EQ(sizeof(buf2), psize);
3687
3688 rados_aio_release(my_completion);
3689 rados_aio_release(my_completion2);
3690 rados_aio_release(my_completion3);
3691 }
3692
3693 TEST(LibRadosAioEC, SimpleStatPPNS) {
3694 AioTestDataECPP test_data;
3695 ASSERT_EQ("", test_data.init());
3696 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
3697 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3698 AioCompletion *my_completion_null = NULL;
3699 ASSERT_NE(my_completion, my_completion_null);
3700 char buf[128];
3701 memset(buf, 0xcc, sizeof(buf));
3702 bufferlist bl1;
3703 bl1.append(buf, sizeof(buf));
3704 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
3705 bl1, sizeof(buf), 0));
3706 {
3707 TestAlarm alarm;
3708 sem_wait(test_data.m_sem);
3709 sem_wait(test_data.m_sem);
3710 }
3711 ASSERT_EQ(0, my_completion->get_return_value());
3712 uint64_t psize;
3713 time_t pmtime;
3714 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
3715 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3716 ASSERT_NE(my_completion2, my_completion_null);
3717 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion2,
3718 &psize, &pmtime));
3719 {
3720 TestAlarm alarm;
3721 ASSERT_EQ(0, my_completion2->wait_for_complete());
3722 }
3723 ASSERT_EQ(0, my_completion2->get_return_value());
3724 ASSERT_EQ(sizeof(buf), psize);
3725 delete my_completion;
3726 delete my_completion2;
3727 }
3728
3729 TEST(LibRadosAioEC, StatRemove) {
3730 AioTestDataEC test_data;
3731 rados_completion_t my_completion;
3732 ASSERT_EQ("", test_data.init());
3733 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3734 set_completion_completeEC, set_completion_safeEC, &my_completion));
3735 char buf[128];
3736 memset(buf, 0xcc, sizeof(buf));
3737 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
3738 my_completion, buf, sizeof(buf), 0));
3739 {
3740 TestAlarm alarm;
3741 sem_wait(test_data.m_sem);
3742 sem_wait(test_data.m_sem);
3743 }
3744 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
3745 uint64_t psize;
3746 time_t pmtime;
3747 rados_completion_t my_completion2;
3748 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3749 set_completion_completeEC, set_completion_safeEC, &my_completion2));
3750 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
3751 my_completion2, &psize, &pmtime));
3752 {
3753 TestAlarm alarm;
3754 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
3755 }
3756 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
3757 ASSERT_EQ(sizeof(buf), psize);
3758 rados_completion_t my_completion3;
3759 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3760 set_completion_completeEC, set_completion_safeEC, &my_completion3));
3761 ASSERT_EQ(0, rados_aio_remove(test_data.m_ioctx, "foo", my_completion3));
3762 {
3763 TestAlarm alarm;
3764 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
3765 }
3766 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3));
3767 uint64_t psize2;
3768 time_t pmtime2;
3769 rados_completion_t my_completion4;
3770 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3771 set_completion_completeEC, set_completion_safeEC, &my_completion4));
3772 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
3773 my_completion4, &psize2, &pmtime2));
3774 {
3775 TestAlarm alarm;
3776 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4));
3777 }
3778 ASSERT_EQ(-ENOENT, rados_aio_get_return_value(my_completion4));
3779 rados_aio_release(my_completion);
3780 rados_aio_release(my_completion2);
3781 rados_aio_release(my_completion3);
3782 rados_aio_release(my_completion4);
3783 }
3784
3785 TEST(LibRadosAioEC, StatRemovePP) {
3786 AioTestDataECPP test_data;
3787 ASSERT_EQ("", test_data.init());
3788 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
3789 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3790 AioCompletion *my_completion_null = NULL;
3791 ASSERT_NE(my_completion, my_completion_null);
3792 char buf[128];
3793 memset(buf, 0xcc, sizeof(buf));
3794 bufferlist bl1;
3795 bl1.append(buf, sizeof(buf));
3796 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
3797 bl1, sizeof(buf), 0));
3798 {
3799 TestAlarm alarm;
3800 sem_wait(test_data.m_sem);
3801 sem_wait(test_data.m_sem);
3802 }
3803 ASSERT_EQ(0, my_completion->get_return_value());
3804 uint64_t psize;
3805 time_t pmtime;
3806 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
3807 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3808 ASSERT_NE(my_completion2, my_completion_null);
3809 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion2,
3810 &psize, &pmtime));
3811 {
3812 TestAlarm alarm;
3813 ASSERT_EQ(0, my_completion2->wait_for_complete());
3814 }
3815 ASSERT_EQ(0, my_completion2->get_return_value());
3816 ASSERT_EQ(sizeof(buf), psize);
3817 uint64_t psize2;
3818 time_t pmtime2;
3819 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
3820 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3821 ASSERT_NE(my_completion3, my_completion_null);
3822 ASSERT_EQ(0, test_data.m_ioctx.aio_remove("foo", my_completion3));
3823 {
3824 TestAlarm alarm;
3825 ASSERT_EQ(0, my_completion3->wait_for_complete());
3826 }
3827 ASSERT_EQ(0, my_completion3->get_return_value());
3828
3829 AioCompletion *my_completion4 = test_data.m_cluster.aio_create_completion(
3830 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3831 ASSERT_NE(my_completion4, my_completion_null);
3832 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion4,
3833 &psize2, &pmtime2));
3834 {
3835 TestAlarm alarm;
3836 ASSERT_EQ(0, my_completion4->wait_for_complete());
3837 }
3838 ASSERT_EQ(-ENOENT, my_completion4->get_return_value());
3839 delete my_completion;
3840 delete my_completion2;
3841 delete my_completion3;
3842 delete my_completion4;
3843 }
3844
3845 TEST(LibRadosAioEC, ExecuteClass) {
3846 AioTestDataEC test_data;
3847 rados_completion_t my_completion;
3848 ASSERT_EQ("", test_data.init());
3849 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3850 set_completion_completeEC, set_completion_safeEC, &my_completion));
3851 char buf[128];
3852 memset(buf, 0xcc, sizeof(buf));
3853 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
3854 my_completion, buf, sizeof(buf), 0));
3855 {
3856 TestAlarm alarm;
3857 sem_wait(test_data.m_sem);
3858 sem_wait(test_data.m_sem);
3859 }
3860 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
3861 rados_completion_t my_completion2;
3862 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3863 set_completion_completeEC, set_completion_safeEC, &my_completion2));
3864 char out[128];
3865 ASSERT_EQ(0, rados_aio_exec(test_data.m_ioctx, "foo", my_completion2,
3866 "hello", "say_hello", NULL, 0, out, sizeof(out)));
3867 {
3868 TestAlarm alarm;
3869 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
3870 }
3871 ASSERT_EQ(13, rados_aio_get_return_value(my_completion2));
3872 ASSERT_EQ(0, strncmp("Hello, world!", out, 13));
3873 rados_aio_release(my_completion);
3874 rados_aio_release(my_completion2);
3875 }
3876
3877 TEST(LibRadosAioEC, ExecuteClassPP) {
3878 AioTestDataECPP test_data;
3879 ASSERT_EQ("", test_data.init());
3880 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
3881 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3882 AioCompletion *my_completion_null = NULL;
3883 ASSERT_NE(my_completion, my_completion_null);
3884 char buf[128];
3885 memset(buf, 0xcc, sizeof(buf));
3886 bufferlist bl1;
3887 bl1.append(buf, sizeof(buf));
3888 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
3889 bl1, sizeof(buf), 0));
3890 {
3891 TestAlarm alarm;
3892 sem_wait(test_data.m_sem);
3893 sem_wait(test_data.m_sem);
3894 }
3895 ASSERT_EQ(0, my_completion->get_return_value());
3896 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
3897 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3898 ASSERT_NE(my_completion2, my_completion_null);
3899 bufferlist in, out;
3900 ASSERT_EQ(0, test_data.m_ioctx.aio_exec("foo", my_completion2,
3901 "hello", "say_hello", in, &out));
3902 {
3903 TestAlarm alarm;
3904 ASSERT_EQ(0, my_completion2->wait_for_complete());
3905 }
3906 ASSERT_EQ(0, my_completion2->get_return_value());
3907 ASSERT_EQ(std::string("Hello, world!"), std::string(out.c_str(), out.length()));
3908 delete my_completion;
3909 delete my_completion2;
3910 }
3911
3912 TEST(LibRadosAioEC, OmapPP) {
3913 Rados cluster;
3914 std::string pool_name = get_temp_pool_name();
3915 ASSERT_EQ("", create_one_ec_pool_pp(pool_name, cluster));
3916 IoCtx ioctx;
3917 cluster.ioctx_create(pool_name.c_str(), ioctx);
3918
3919 string header_str = "baz";
3920 bufferptr bp(header_str.c_str(), header_str.size() + 1);
3921 bufferlist header_to_set;
3922 header_to_set.push_back(bp);
3923 map<string, bufferlist> to_set;
3924 {
3925 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
3926 ObjectWriteOperation op;
3927 to_set["foo"] = header_to_set;
3928 to_set["foo2"] = header_to_set;
3929 to_set["qfoo3"] = header_to_set;
3930 op.omap_set(to_set);
3931
3932 op.omap_set_header(header_to_set);
3933
3934 ioctx.aio_operate("test_obj", my_completion.get(), &op);
3935 {
3936 TestAlarm alarm;
3937 ASSERT_EQ(0, my_completion->wait_for_complete());
3938 }
3939 EXPECT_EQ(-EOPNOTSUPP, my_completion->get_return_value());
3940 }
3941 ioctx.remove("test_obj");
3942 destroy_one_pool_pp(pool_name, cluster);
3943 }
3944
3945 TEST(LibRadosAioEC, MultiWrite) {
3946 AioTestDataEC test_data;
3947 rados_completion_t my_completion, my_completion2, my_completion3;
3948 ASSERT_EQ("", test_data.init());
3949 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3950 set_completion_completeEC, set_completion_safeEC, &my_completion));
3951 char buf[128];
3952 memset(buf, 0xcc, sizeof(buf));
3953 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
3954 my_completion, buf, sizeof(buf), 0));
3955 {
3956 TestAlarm alarm;
3957 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
3958 }
3959 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
3960
3961 char buf2[64];
3962 memset(buf2, 0xdd, sizeof(buf2));
3963 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3964 set_completion_completeEC, set_completion_safeEC, &my_completion2));
3965 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
3966 my_completion2, buf2, sizeof(buf2), sizeof(buf)));
3967 {
3968 TestAlarm alarm;
3969 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
3970 }
3971 ASSERT_EQ(-EOPNOTSUPP, rados_aio_get_return_value(my_completion2));
3972
3973 char buf3[(sizeof(buf) + sizeof(buf2)) * 3];
3974 memset(buf3, 0, sizeof(buf3));
3975 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
3976 set_completion_completeEC, set_completion_safeEC, &my_completion3));
3977 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
3978 my_completion3, buf3, sizeof(buf3), 0));
3979 {
3980 TestAlarm alarm;
3981 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
3982 }
3983 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion3));
3984 ASSERT_EQ(0, memcmp(buf3, buf, sizeof(buf)));
3985 rados_aio_release(my_completion);
3986 rados_aio_release(my_completion2);
3987 rados_aio_release(my_completion3);
3988 }
3989
3990 TEST(LibRadosAioEC, MultiWritePP) {
3991 AioTestDataECPP test_data;
3992 ASSERT_EQ("", test_data.init());
3993 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
3994 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
3995 AioCompletion *my_completion_null = NULL;
3996 ASSERT_NE(my_completion, my_completion_null);
3997 char buf[128];
3998 memset(buf, 0xcc, sizeof(buf));
3999 bufferlist bl1;
4000 bl1.append(buf, sizeof(buf));
4001 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
4002 bl1, sizeof(buf), 0));
4003 {
4004 TestAlarm alarm;
4005 ASSERT_EQ(0, my_completion->wait_for_complete());
4006 }
4007 ASSERT_EQ(0, my_completion->get_return_value());
4008
4009 char buf2[64];
4010 memset(buf2, 0xdd, sizeof(buf2));
4011 bufferlist bl2;
4012 bl2.append(buf2, sizeof(buf2));
4013 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
4014 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
4015 ASSERT_NE(my_completion2, my_completion_null);
4016 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion2,
4017 bl2, sizeof(buf2), sizeof(buf)));
4018 {
4019 TestAlarm alarm;
4020 ASSERT_EQ(0, my_completion2->wait_for_complete());
4021 }
4022 ASSERT_EQ(-EOPNOTSUPP, my_completion2->get_return_value());
4023
4024 bufferlist bl3;
4025 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
4026 (void*)&test_data, set_completion_completeEC, set_completion_safeEC);
4027 ASSERT_NE(my_completion3, my_completion_null);
4028 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion3,
4029 &bl3, (sizeof(buf) + sizeof(buf2) * 3), 0));
4030 {
4031 TestAlarm alarm;
4032 ASSERT_EQ(0, my_completion3->wait_for_complete());
4033 }
4034 ASSERT_EQ((int)sizeof(buf), my_completion3->get_return_value());
4035 ASSERT_EQ(sizeof(buf), bl3.length());
4036 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
4037 delete my_completion;
4038 delete my_completion2;
4039 delete my_completion3;
4040 }
4041
4042 TEST(LibRadosAio, RacingRemovePP) {
4043 AioTestDataPP test_data;
4044 ASSERT_EQ("", test_data.init({{"objecter_retry_writes_after_first_reply", "true"}}));
4045 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
4046 (void*)&test_data, set_completion_complete, set_completion_safe);
4047 ASSERT_NE(my_completion, nullptr);
4048 char buf[128];
4049 memset(buf, 0xcc, sizeof(buf));
4050 bufferlist bl;
4051 bl.append(buf, sizeof(buf));
4052 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
4053 (void*)&test_data, set_completion_complete, set_completion_safe);
4054 ASSERT_NE(my_completion2, nullptr);
4055 ASSERT_EQ(0, test_data.m_ioctx.aio_remove("foo", my_completion2));
4056 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
4057 bl, sizeof(buf), 0));
4058 {
4059 TestAlarm alarm;
4060 sem_wait(test_data.m_sem);
4061 sem_wait(test_data.m_sem);
4062 my_completion2->wait_for_complete();
4063 my_completion->wait_for_complete();
4064 }
4065 ASSERT_EQ(-ENOENT, my_completion2->get_return_value());
4066 ASSERT_EQ(0, my_completion->get_return_value());
4067 ASSERT_EQ(0, test_data.m_ioctx.stat("foo", nullptr, nullptr));
4068 delete my_completion;
4069 delete my_completion2;
4070 }
4071
4072 TEST(LibRadosAio, RoundTripCmpExtPP) {
4073 AioTestDataPP test_data;
4074 ASSERT_EQ("", test_data.init());
4075 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
4076 (void*)&test_data, set_completion_complete, set_completion_safe);
4077 AioCompletion *my_completion_null = NULL;
4078 ASSERT_NE(my_completion, my_completion_null);
4079 char full[128];
4080 memset(full, 0xcc, sizeof(full));
4081 bufferlist bl1;
4082 bl1.append(full, sizeof(full));
4083 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
4084 bl1, sizeof(full), 0));
4085 {
4086 TestAlarm alarm;
4087 ASSERT_EQ(0, my_completion->wait_for_complete());
4088 }
4089 ASSERT_EQ(0, my_completion->get_return_value());
4090
4091 /* compare with match */
4092 bufferlist cbl;
4093 cbl.append(full, sizeof(full));
4094 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
4095 (void*)&test_data, set_completion_complete, set_completion_safe);
4096 ASSERT_EQ(0, test_data.m_ioctx.aio_cmpext("foo", my_completion2, 0, cbl));
4097
4098 {
4099 TestAlarm alarm;
4100 ASSERT_EQ(0, my_completion2->wait_for_complete());
4101 }
4102 ASSERT_EQ(0, my_completion2->get_return_value());
4103
4104 /* compare with mismatch */
4105 memset(full, 0xdd, sizeof(full));
4106 cbl.clear();
4107 cbl.append(full, sizeof(full));
4108 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
4109 (void*)&test_data, set_completion_complete, set_completion_safe);
4110 ASSERT_EQ(0, test_data.m_ioctx.aio_cmpext("foo", my_completion3, 0, cbl));
4111
4112 {
4113 TestAlarm alarm;
4114 ASSERT_EQ(0, my_completion3->wait_for_complete());
4115 }
4116 ASSERT_EQ(-MAX_ERRNO, my_completion3->get_return_value());
4117
4118 delete my_completion;
4119 delete my_completion2;
4120 delete my_completion3;
4121 }
4122
4123 TEST(LibRadosAio, RoundTripCmpExtPP2)
4124 {
4125 int ret;
4126 char buf[128];
4127 char miscmp_buf[128];
4128 bufferlist cbl;
4129 Rados cluster;
4130 std::string pool_name = get_temp_pool_name();
4131 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
4132 IoCtx ioctx;
4133 cluster.ioctx_create(pool_name.c_str(), ioctx);
4134
4135 boost::scoped_ptr<AioCompletion>
4136 wr_cmpl(cluster.aio_create_completion(0, 0, 0));
4137 ObjectWriteOperation wr_op;
4138 memset(buf, 0xcc, sizeof(buf));
4139 memset(miscmp_buf, 0xdd, sizeof(miscmp_buf));
4140 bufferlist bl;
4141 bl.append(buf, sizeof(buf));
4142
4143 wr_op.write_full(bl);
4144 wr_op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
4145 ioctx.aio_operate("test_obj", wr_cmpl.get(), &wr_op);
4146 {
4147 TestAlarm alarm;
4148 ASSERT_EQ(0, wr_cmpl->wait_for_complete());
4149 }
4150 EXPECT_EQ(0, wr_cmpl->get_return_value());
4151
4152 /* cmpext as write op. first match then mismatch */
4153 boost::scoped_ptr<AioCompletion>
4154 wr_cmpext_cmpl(cluster.aio_create_completion(0, 0, 0));
4155 cbl.append(buf, sizeof(buf));
4156 ret = 0;
4157
4158 wr_op.cmpext(0, cbl, &ret);
4159 wr_op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
4160 ioctx.aio_operate("test_obj", wr_cmpext_cmpl.get(), &wr_op);
4161 {
4162 TestAlarm alarm;
4163 ASSERT_EQ(0, wr_cmpext_cmpl->wait_for_complete());
4164 }
4165 EXPECT_EQ(0, wr_cmpext_cmpl->get_return_value());
4166 EXPECT_EQ(0, ret);
4167
4168 boost::scoped_ptr<AioCompletion>
4169 wr_cmpext_cmpl2(cluster.aio_create_completion(0, 0, 0));
4170 cbl.clear();
4171 cbl.append(miscmp_buf, sizeof(miscmp_buf));
4172 ret = 0;
4173
4174 wr_op.cmpext(0, cbl, &ret);
4175 wr_op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
4176 ioctx.aio_operate("test_obj", wr_cmpext_cmpl2.get(), &wr_op);
4177 {
4178 TestAlarm alarm;
4179 ASSERT_EQ(0, wr_cmpext_cmpl2->wait_for_complete());
4180 }
4181 EXPECT_EQ(-MAX_ERRNO, wr_cmpext_cmpl2->get_return_value());
4182 EXPECT_EQ(-MAX_ERRNO, ret);
4183
4184 /* cmpext as read op */
4185 boost::scoped_ptr<AioCompletion>
4186 rd_cmpext_cmpl(cluster.aio_create_completion(0, 0, 0));
4187 ObjectReadOperation rd_op;
4188 cbl.clear();
4189 cbl.append(buf, sizeof(buf));
4190 ret = 0;
4191 rd_op.cmpext(0, cbl, &ret);
4192 rd_op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
4193 ioctx.aio_operate("test_obj", rd_cmpext_cmpl.get(), &rd_op, 0);
4194 {
4195 TestAlarm alarm;
4196 ASSERT_EQ(0, rd_cmpext_cmpl->wait_for_complete());
4197 }
4198 EXPECT_EQ(0, rd_cmpext_cmpl->get_return_value());
4199 EXPECT_EQ(0, ret);
4200
4201 boost::scoped_ptr<AioCompletion>
4202 rd_cmpext_cmpl2(cluster.aio_create_completion(0, 0, 0));
4203 cbl.clear();
4204 cbl.append(miscmp_buf, sizeof(miscmp_buf));
4205 ret = 0;
4206
4207 rd_op.cmpext(0, cbl, &ret);
4208 rd_op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
4209 ioctx.aio_operate("test_obj", rd_cmpext_cmpl2.get(), &rd_op, 0);
4210 {
4211 TestAlarm alarm;
4212 ASSERT_EQ(0, rd_cmpext_cmpl2->wait_for_complete());
4213 }
4214 EXPECT_EQ(-MAX_ERRNO, rd_cmpext_cmpl2->get_return_value());
4215 EXPECT_EQ(-MAX_ERRNO, ret);
4216
4217 ioctx.remove("test_obj");
4218 destroy_one_pool_pp(pool_name, cluster);
4219 }