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