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