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