]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/librados/aio_cxx.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / test / librados / aio_cxx.cc
CommitLineData
11fdf7f2
TL
1#include <errno.h>
2#include <fcntl.h>
3#include <sstream>
4#include <string>
5#include <utility>
6#include <boost/scoped_ptr.hpp>
7
8#include "gtest/gtest.h"
9
10#include "common/errno.h"
11#include "include/err.h"
12#include "include/rados/librados.hpp"
13#include "include/types.h"
14#include "include/stringify.h"
15#include "include/scope_guard.h"
16
17#include "test_cxx.h"
18
19using namespace librados;
20using std::pair;
21using std::ostringstream;
22
23class AioTestDataPP
24{
25public:
26 AioTestDataPP()
27 : m_init(false)
28 {
29 }
30
31 ~AioTestDataPP()
32 {
33 if (m_init) {
34 m_ioctx.close();
35 destroy_one_pool_pp(m_pool_name, m_cluster);
36 }
37 }
38
39 std::string init()
40 {
41 return init({});
42 }
43
44 std::string init(const std::map<std::string, std::string> &config)
45 {
46 int ret;
47
48 m_pool_name = get_temp_pool_name();
49 std::string err = create_one_pool_pp(m_pool_name, m_cluster, config);
50 if (!err.empty()) {
51 ostringstream oss;
52 oss << "create_one_pool(" << m_pool_name << ") failed: error " << err;
53 return oss.str();
54 }
55 ret = m_cluster.ioctx_create(m_pool_name.c_str(), m_ioctx);
56 if (ret) {
57 destroy_one_pool_pp(m_pool_name, m_cluster);
58 ostringstream oss;
59 oss << "rados_ioctx_create failed: error " << ret;
60 return oss.str();
61 }
62 m_init = true;
63 return "";
64 }
65
66 Rados m_cluster;
67 IoCtx m_ioctx;
68 std::string m_pool_name;
69 bool m_init;
70};
71
72TEST(LibRadosAio, TooBigPP) {
73 AioTestDataPP test_data;
74 ASSERT_EQ("", test_data.init());
75
76 bufferlist bl;
77 AioCompletion *aio_completion = test_data.m_cluster.aio_create_completion(nullptr, NULL, NULL);
78 ASSERT_EQ(-E2BIG, test_data.m_ioctx.aio_write("foo", aio_completion, bl, UINT_MAX, 0));
79 ASSERT_EQ(-E2BIG, test_data.m_ioctx.aio_append("foo", aio_completion, bl, UINT_MAX));
80 // ioctx.aio_write_full no way to overflow bl.length()
81 delete aio_completion;
82}
83
84TEST(LibRadosAio, PoolQuotaPP) {
85 AioTestDataPP test_data;
86 ASSERT_EQ("", test_data.init());
87 string p = get_temp_pool_name();
88 ASSERT_EQ(0, test_data.m_cluster.pool_create(p.c_str()));
89 IoCtx ioctx;
90 ASSERT_EQ(0, test_data.m_cluster.ioctx_create(p.c_str(), ioctx));
91 ioctx.application_enable("rados", true);
92
93 bufferlist inbl;
94 ASSERT_EQ(0, test_data.m_cluster.mon_command(
95 "{\"prefix\": \"osd pool set-quota\", \"pool\": \"" + p +
96 "\", \"field\": \"max_bytes\", \"val\": \"4096\"}",
97 inbl, NULL, NULL));
98
99 bufferlist bl;
100 bufferptr z(4096);
101 bl.append(z);
102 int n;
103 for (n = 0; n < 1024; ++n) {
104 ObjectWriteOperation op;
105 op.write_full(bl);
106 librados::AioCompletion *completion =
107 test_data.m_cluster.aio_create_completion();
108 ASSERT_EQ(0, ioctx.aio_operate(
109 "foo" + stringify(n), completion, &op,
110 librados::OPERATION_FULL_TRY));
111 completion->wait_for_safe();
112 int r = completion->get_return_value();
113 completion->release();
114 if (r == -EDQUOT)
115 break;
116 ASSERT_EQ(0, r);
117 sleep(1);
118 }
119 ASSERT_LT(n, 1024);
120
121 // make sure we have latest map that marked the pool full
122 test_data.m_cluster.wait_for_latest_osdmap();
123
124 // make sure we block without FULL_TRY
125 {
126 ObjectWriteOperation op;
127 op.write_full(bl);
128 librados::AioCompletion *completion =
129 test_data.m_cluster.aio_create_completion();
130 ASSERT_EQ(0, ioctx.aio_operate("bar", completion, &op, 0));
131 sleep(5);
132 ASSERT_FALSE(completion->is_safe());
133 completion->release();
134 }
135
136 ioctx.close();
137 ASSERT_EQ(0, test_data.m_cluster.pool_delete(p.c_str()));
138}
139
140TEST(LibRadosAio, SimpleWritePP) {
141 char buf[128];
142 memset(buf, 0xcc, sizeof(buf));
143 bufferlist bl1;
144 bl1.append(buf, sizeof(buf));
145 {
146 AioTestDataPP test_data;
147 ASSERT_EQ("", test_data.init());
148 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
149 nullptr, nullptr, nullptr);
150 AioCompletion *my_completion_null = NULL;
151 ASSERT_NE(my_completion, my_completion_null);
152 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
153 my_completion, bl1, sizeof(buf), 0));
154 {
155 TestAlarm alarm;
156 ASSERT_EQ(0, my_completion->wait_for_complete());
157 }
158 ASSERT_EQ(0, my_completion->get_return_value());
159 delete my_completion;
160 }
161
162 {
163 AioTestDataPP test_data;
164 ASSERT_EQ("", test_data.init());
165 test_data.m_ioctx.set_namespace("nspace");
166 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
167 nullptr, nullptr, nullptr);
168 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
169 my_completion, bl1, sizeof(buf), 0));
170 {
171 TestAlarm alarm;
172 ASSERT_EQ(0, my_completion->wait_for_complete());
173 }
174 ASSERT_EQ(0, my_completion->get_return_value());
175 delete my_completion;
176 }
177}
178
179TEST(LibRadosAio, WaitForSafePP) {
180 AioTestDataPP test_data;
181 ASSERT_EQ("", test_data.init());
182 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
183 nullptr, nullptr, nullptr);
184 AioCompletion *my_completion_null = NULL;
185 ASSERT_NE(my_completion, my_completion_null);
186 char buf[128];
187 memset(buf, 0xcc, sizeof(buf));
188 bufferlist bl1;
189 bl1.append(buf, sizeof(buf));
190 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
191 my_completion, bl1, sizeof(buf), 0));
192 TestAlarm alarm;
193 ASSERT_EQ(0, my_completion->wait_for_safe());
194 ASSERT_EQ(0, my_completion->get_return_value());
195 delete my_completion;
196}
197
198TEST(LibRadosAio, RoundTripPP) {
199 AioTestDataPP test_data;
200 ASSERT_EQ("", test_data.init());
201 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
202 nullptr, nullptr, nullptr);
203 AioCompletion *my_completion_null = NULL;
204 ASSERT_NE(my_completion, my_completion_null);
205 char buf[128];
206 memset(buf, 0xcc, sizeof(buf));
207 bufferlist bl1;
208 bl1.append(buf, sizeof(buf));
209 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
210 bl1, sizeof(buf), 0));
211 {
212 TestAlarm alarm;
213 ASSERT_EQ(0, my_completion->wait_for_complete());
214 }
215 ASSERT_EQ(0, my_completion->get_return_value());
216 bufferlist bl2;
217 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
218 nullptr, nullptr, nullptr);
219 ASSERT_NE(my_completion2, my_completion_null);
220 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo",
221 my_completion2, &bl2, sizeof(buf), 0));
222 {
223 TestAlarm alarm;
224 ASSERT_EQ(0, my_completion2->wait_for_complete());
225 }
226 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
227 ASSERT_EQ(sizeof(buf), bl2.length());
228 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
229 delete my_completion;
230 delete my_completion2;
231}
232
233TEST(LibRadosAio, RoundTripPP2) {
234 AioTestDataPP test_data;
235 ASSERT_EQ("", test_data.init());
236 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
237 nullptr, nullptr, nullptr);
238 AioCompletion *my_completion_null = NULL;
239 ASSERT_NE(my_completion, my_completion_null);
240 char buf[128];
241 memset(buf, 0xcc, sizeof(buf));
242 bufferlist bl1;
243 bl1.append(buf, sizeof(buf));
244 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
245 bl1, sizeof(buf), 0));
246 {
247 TestAlarm alarm;
248 ASSERT_EQ(0, my_completion->wait_for_complete());
249 }
250 ASSERT_EQ(0, my_completion->get_return_value());
251 bufferlist bl2;
252 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
253 nullptr, nullptr, nullptr);
254 ASSERT_NE(my_completion2, my_completion_null);
255 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo",
256 my_completion2, &bl2, sizeof(buf), 0));
257 {
258 TestAlarm alarm;
259 ASSERT_EQ(0, my_completion2->wait_for_safe());
260 ASSERT_EQ(0, my_completion2->wait_for_complete());
261 }
262 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
263 ASSERT_EQ(sizeof(buf), bl2.length());
264 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
265 delete my_completion;
266 delete my_completion2;
267}
268
269//using ObjectWriteOperation/ObjectReadOperation with iohint
270TEST(LibRadosAio, RoundTripPP3)
271{
272 Rados cluster;
273 std::string pool_name = get_temp_pool_name();
274 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
275 IoCtx ioctx;
276 cluster.ioctx_create(pool_name.c_str(), ioctx);
277
278 boost::scoped_ptr<AioCompletion> my_completion1(cluster.aio_create_completion(0, 0, 0));
279 ObjectWriteOperation op;
280 char buf[128];
281 memset(buf, 0xcc, sizeof(buf));
282 bufferlist bl;
283 bl.append(buf, sizeof(buf));
284
285 op.write(0, bl);
286 op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
287 ioctx.aio_operate("test_obj", my_completion1.get(), &op);
288 {
289 TestAlarm alarm;
290 ASSERT_EQ(0, my_completion1->wait_for_complete());
291 }
292 EXPECT_EQ(0, my_completion1->get_return_value());
293
294 boost::scoped_ptr<AioCompletion> my_completion2(cluster.aio_create_completion(0, 0, 0));
295 bl.clear();
296 ObjectReadOperation op1;
297 op1.read(0, sizeof(buf), &bl, NULL);
298 op1.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED|LIBRADOS_OP_FLAG_FADVISE_RANDOM);
299 bufferlist init_value_bl;
300 encode(static_cast<int32_t>(-1), init_value_bl);
301 bufferlist csum_bl;
302 op1.checksum(LIBRADOS_CHECKSUM_TYPE_CRC32C, init_value_bl,
303 0, 0, 0, &csum_bl, nullptr);
304 ioctx.aio_operate("test_obj", my_completion2.get(), &op1, 0);
305 {
306 TestAlarm alarm;
307 ASSERT_EQ(0, my_completion2->wait_for_complete());
308 }
309 EXPECT_EQ(0, my_completion2->get_return_value());
310 ASSERT_EQ(0, memcmp(buf, bl.c_str(), sizeof(buf)));
311
312 ASSERT_EQ(8U, csum_bl.length());
313 auto csum_bl_it = csum_bl.cbegin();
314 uint32_t csum_count;
315 uint32_t csum;
316 decode(csum_count, csum_bl_it);
317 ASSERT_EQ(1U, csum_count);
318 decode(csum, csum_bl_it);
319 ASSERT_EQ(bl.crc32c(-1), csum);
320 ioctx.remove("test_obj");
321 destroy_one_pool_pp(pool_name, cluster);
322}
323
324TEST(LibRadosAio, RoundTripSparseReadPP) {
325 AioTestDataPP test_data;
326 ASSERT_EQ("", test_data.init());
327 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
328 nullptr, nullptr, nullptr);
329 AioCompletion *my_completion_null = NULL;
330 ASSERT_NE(my_completion, my_completion_null);
331 char buf[128];
332 memset(buf, 0xcc, sizeof(buf));
333 bufferlist bl1;
334 bl1.append(buf, sizeof(buf));
335 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
336 bl1, sizeof(buf), 0));
337 {
338 TestAlarm alarm;
339 ASSERT_EQ(0, my_completion->wait_for_complete());
340 }
341 ASSERT_EQ(0, my_completion->get_return_value());
342 std::map<uint64_t, uint64_t> extents;
343 bufferlist bl2;
344 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
345 nullptr, nullptr, nullptr);
346 ASSERT_NE(my_completion2, my_completion_null);
347 ASSERT_EQ(0, test_data.m_ioctx.aio_sparse_read("foo",
348 my_completion2, &extents, &bl2, sizeof(buf), 0));
349 {
350 TestAlarm alarm;
351 ASSERT_EQ(0, my_completion2->wait_for_complete());
352 }
353 ASSERT_EQ(0, my_completion2->get_return_value());
354 assert_eq_sparse(bl1, extents, bl2);
355 delete my_completion;
356 delete my_completion2;
357}
358
359TEST(LibRadosAioPP, ReadIntoBufferlist) {
360
361 // here we test reading into a non-empty bufferlist referencing existing
362 // buffers
363
364 AioTestDataPP test_data;
365 ASSERT_EQ("", test_data.init());
366 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
367 nullptr, nullptr, nullptr);
368 AioCompletion *my_completion_null = NULL;
369 ASSERT_NE(my_completion, my_completion_null);
370 char buf[128];
371 memset(buf, 0xcc, sizeof(buf));
372 bufferlist bl1;
373 bl1.append(buf, sizeof(buf));
374 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
375 bl1, sizeof(buf), 0));
376 {
377 TestAlarm alarm;
378 ASSERT_EQ(0, my_completion->wait_for_complete());
379 }
380 ASSERT_EQ(0, my_completion->get_return_value());
381
382 bufferlist bl2;
383 char buf2[sizeof(buf)];
384 memset(buf2, 0xbb, sizeof(buf2));
385 bl2.append(buffer::create_static(sizeof(buf2), buf2));
386 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
387 nullptr, nullptr, nullptr);
388 ASSERT_NE(my_completion2, my_completion_null);
389 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
390 &bl2, sizeof(buf), 0));
391 {
392 TestAlarm alarm;
393 ASSERT_EQ(0, my_completion2->wait_for_complete());
394 }
395 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
396 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
397 delete my_completion;
398 delete my_completion2;
399}
400
401TEST(LibRadosAioPP, XattrsRoundTripPP) {
402 char buf[128];
403 char attr1[] = "attr1";
404 char attr1_buf[] = "foo bar baz";
405 memset(buf, 0xaa, sizeof(buf));
406 bufferlist bl1;
407 bl1.append(buf, sizeof(buf));
408 AioTestDataPP test_data;
409 ASSERT_EQ("", test_data.init());
410 ASSERT_EQ(0, test_data.m_ioctx.append("foo", bl1, sizeof(buf)));
411 bufferlist bl2;
412 // async getxattr
413 boost::scoped_ptr<AioCompletion> my_completion
414 (test_data.m_cluster.aio_create_completion
415 (nullptr, nullptr, nullptr));
416 ASSERT_EQ(0, test_data.m_ioctx.aio_getxattr("foo", my_completion.get(), attr1, bl2));
417 {
418 TestAlarm alarm;
419 ASSERT_EQ(0, my_completion->wait_for_complete());
420 }
421 ASSERT_EQ(-ENODATA, my_completion->get_return_value());
422 // append
423 bufferlist bl3;
424 bl3.append(attr1_buf, sizeof(attr1_buf));
425 // async setxattr
426 AioTestDataPP test_data2;
427 ASSERT_EQ("", test_data2.init());
428 boost::scoped_ptr<AioCompletion> my_completion2
429 (test_data.m_cluster.aio_create_completion
430 (nullptr, nullptr, nullptr));
431 ASSERT_EQ(0, test_data.m_ioctx.aio_setxattr("foo", my_completion2.get(), attr1, bl3));
432 {
433 TestAlarm alarm;
434 ASSERT_EQ(0, my_completion2->wait_for_complete());
435 }
436 ASSERT_EQ(0, my_completion2->get_return_value());
437 // async getxattr
438 bufferlist bl4;
439 AioTestDataPP test_data3;
440 ASSERT_EQ("", test_data3.init());
441 boost::scoped_ptr<AioCompletion> my_completion3
442 (test_data.m_cluster.aio_create_completion
443 (nullptr, nullptr, nullptr));
444 ASSERT_EQ(0, test_data.m_ioctx.aio_getxattr("foo", my_completion3.get(), attr1, bl4));
445 {
446 TestAlarm alarm;
447 ASSERT_EQ(0, my_completion3->wait_for_complete());
448 }
449 ASSERT_EQ((int)sizeof(attr1_buf), my_completion3->get_return_value());
450 // check content of attribute
451 ASSERT_EQ(0, memcmp(bl4.c_str(), attr1_buf, sizeof(attr1_buf)));
452}
453
454TEST(LibRadosAioPP, RmXattrPP) {
455 char buf[128];
456 char attr1[] = "attr1";
457 char attr1_buf[] = "foo bar baz";
458 memset(buf, 0xaa, sizeof(buf));
459 bufferlist bl1;
460 bl1.append(buf, sizeof(buf));
461 AioTestDataPP test_data;
462 ASSERT_EQ("", test_data.init());
463 ASSERT_EQ(0, test_data.m_ioctx.append("foo", bl1, sizeof(buf)));
464 // async setxattr
465 bufferlist bl2;
466 bl2.append(attr1_buf, sizeof(attr1_buf));
467 boost::scoped_ptr<AioCompletion> my_completion
468 (test_data.m_cluster.aio_create_completion
469 (nullptr, nullptr, nullptr));
470 ASSERT_EQ(0, test_data.m_ioctx.aio_setxattr("foo", my_completion.get(), attr1, bl2));
471 {
472 TestAlarm alarm;
473 ASSERT_EQ(0, my_completion->wait_for_complete());
474 }
475 ASSERT_EQ(0, my_completion->get_return_value());
476 // async rmxattr
477 AioTestDataPP test_data2;
478 ASSERT_EQ("", test_data2.init());
479 boost::scoped_ptr<AioCompletion> my_completion2
480 (test_data.m_cluster.aio_create_completion
481 (nullptr, nullptr, nullptr));
482 ASSERT_EQ(0, test_data.m_ioctx.aio_rmxattr("foo", my_completion2.get(), attr1));
483 {
484 TestAlarm alarm;
485 ASSERT_EQ(0, my_completion2->wait_for_complete());
486 }
487 ASSERT_EQ(0, my_completion2->get_return_value());
488 // async getxattr
489 AioTestDataPP test_data3;
490 ASSERT_EQ("", test_data3.init());
491 boost::scoped_ptr<AioCompletion> my_completion3
492 (test_data.m_cluster.aio_create_completion
493 (nullptr, nullptr, nullptr));
494 bufferlist bl3;
495 ASSERT_EQ(0, test_data.m_ioctx.aio_getxattr("foo", my_completion3.get(), attr1, bl3));
496 {
497 TestAlarm alarm;
498 ASSERT_EQ(0, my_completion3->wait_for_complete());
499 }
500 ASSERT_EQ(-ENODATA, my_completion3->get_return_value());
501 // Test rmxattr on a removed object
502 char buf2[128];
503 char attr2[] = "attr2";
504 char attr2_buf[] = "foo bar baz";
505 memset(buf2, 0xbb, sizeof(buf2));
506 bufferlist bl21;
507 bl21.append(buf, sizeof(buf));
508 ASSERT_EQ(0, test_data.m_ioctx.write("foo_rmxattr", bl21, sizeof(buf2), 0));
509 bufferlist bl22;
510 bl22.append(attr2_buf, sizeof(attr2_buf));
511 // async setxattr
512 AioTestDataPP test_data4;
513 ASSERT_EQ("", test_data4.init());
514 boost::scoped_ptr<AioCompletion> my_completion4
515 (test_data.m_cluster.aio_create_completion
516 (nullptr, nullptr, nullptr));
517 ASSERT_EQ(0, test_data.m_ioctx.aio_setxattr("foo_rmxattr", my_completion4.get(), attr2, bl22));
518 {
519 TestAlarm alarm;
520 ASSERT_EQ(0, my_completion4->wait_for_complete());
521 }
522 ASSERT_EQ(0, my_completion4->get_return_value());
523 // remove object
524 ASSERT_EQ(0, test_data.m_ioctx.remove("foo_rmxattr"));
525 // async rmxattr on non existing object
526 AioTestDataPP test_data5;
527 ASSERT_EQ("", test_data5.init());
528 boost::scoped_ptr<AioCompletion> my_completion5
529 (test_data.m_cluster.aio_create_completion
530 (nullptr, nullptr, nullptr));
531 ASSERT_EQ(0, test_data.m_ioctx.aio_rmxattr("foo_rmxattr", my_completion5.get(), attr2));
532 {
533 TestAlarm alarm;
534 ASSERT_EQ(0, my_completion5->wait_for_complete());
535 }
536 ASSERT_EQ(-ENOENT, my_completion5->get_return_value());
537}
538
539TEST(LibRadosIoPP, XattrListPP) {
540 AioTestDataPP test_data;
541 ASSERT_EQ("", test_data.init());
542 // create an object with 2 attributes
543 char buf[128];
544 char attr1[] = "attr1";
545 char attr1_buf[] = "foo bar baz";
546 char attr2[] = "attr2";
547 char attr2_buf[256];
548 for (size_t j = 0; j < sizeof(attr2_buf); ++j) {
549 attr2_buf[j] = j % 0xff;
550 }
551 memset(buf, 0xaa, sizeof(buf));
552 bufferlist bl1;
553 bl1.append(buf, sizeof(buf));
554 ASSERT_EQ(0, test_data.m_ioctx.append("foo", bl1, sizeof(buf)));
555 bufferlist bl2;
556 bl2.append(attr1_buf, sizeof(attr1_buf));
557 ASSERT_EQ(0, test_data.m_ioctx.setxattr("foo", attr1, bl2));
558 bufferlist bl3;
559 bl3.append(attr2_buf, sizeof(attr2_buf));
560 ASSERT_EQ(0, test_data.m_ioctx.setxattr("foo", attr2, bl3));
561 // call async version of getxattrs
562 boost::scoped_ptr<AioCompletion> my_completion
563 (test_data.m_cluster.aio_create_completion
564 (nullptr, nullptr, nullptr));
565 std::map<std::string, bufferlist> attrset;
566 ASSERT_EQ(0, test_data.m_ioctx.aio_getxattrs("foo", my_completion.get(), attrset));
567 {
568 TestAlarm alarm;
569 ASSERT_EQ(0, my_completion->wait_for_complete());
570 }
571 ASSERT_EQ(0, my_completion->get_return_value());
572 for (std::map<std::string, bufferlist>::iterator i = attrset.begin();
573 i != attrset.end(); ++i) {
574 if (i->first == string(attr1)) {
575 ASSERT_EQ(0, memcmp(i->second.c_str(), attr1_buf, sizeof(attr1_buf)));
576 }
577 else if (i->first == string(attr2)) {
578 ASSERT_EQ(0, memcmp(i->second.c_str(), attr2_buf, sizeof(attr2_buf)));
579 }
580 else {
581 ASSERT_EQ(0, 1);
582 }
583 }
584}
585
586TEST(LibRadosAio, IsCompletePP) {
587 AioTestDataPP test_data;
588 ASSERT_EQ("", test_data.init());
589 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
590 nullptr, nullptr, nullptr);
591 AioCompletion *my_completion_null = NULL;
592 ASSERT_NE(my_completion, my_completion_null);
593 char buf[128];
594 memset(buf, 0xcc, sizeof(buf));
595 bufferlist bl1;
596 bl1.append(buf, sizeof(buf));
597 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
598 bl1, sizeof(buf), 0));
599 {
600 TestAlarm alarm;
601 ASSERT_EQ(0, my_completion->wait_for_complete());
602 }
603 ASSERT_EQ(0, my_completion->get_return_value());
604 bufferlist bl2;
605 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
606 nullptr, nullptr, nullptr);
607 ASSERT_NE(my_completion2, my_completion_null);
608 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
609 &bl2, sizeof(buf), 0));
610 {
611 TestAlarm alarm;
612
613 // Busy-wait until the AIO completes.
614 // Normally we wouldn't do this, but we want to test is_complete.
615 while (true) {
616 int is_complete = my_completion2->is_complete();
617 if (is_complete)
618 break;
619 }
620 }
621 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
622 ASSERT_EQ(sizeof(buf), bl2.length());
623 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
624 delete my_completion;
625 delete my_completion2;
626}
627
628TEST(LibRadosAio, IsSafePP) {
629 AioTestDataPP test_data;
630 ASSERT_EQ("", test_data.init());
631 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
632 nullptr, nullptr, nullptr);
633 AioCompletion *my_completion_null = NULL;
634 ASSERT_NE(my_completion, my_completion_null);
635 char buf[128];
636 memset(buf, 0xcc, sizeof(buf));
637 bufferlist bl1;
638 bl1.append(buf, sizeof(buf));
639 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
640 bl1, sizeof(buf), 0));
641 {
642 TestAlarm alarm;
643
644 // Busy-wait until the AIO completes.
645 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
646 while (true) {
647 int is_safe = my_completion->is_safe();
648 if (is_safe)
649 break;
650 }
651 }
652 ASSERT_EQ(0, my_completion->get_return_value());
653 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
654 nullptr, nullptr, nullptr);
655 bufferlist bl2;
656 ASSERT_NE(my_completion2, my_completion_null);
657 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
658 &bl2, sizeof(buf), 0));
659 {
660 TestAlarm alarm;
661 ASSERT_EQ(0, my_completion2->wait_for_complete());
662 }
663 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
664 ASSERT_EQ(sizeof(buf), bl2.length());
665 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
666 delete my_completion;
667 delete my_completion2;
668}
669
670TEST(LibRadosAio, ReturnValuePP) {
671 AioTestDataPP test_data;
672 ASSERT_EQ("", test_data.init());
673 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
674 nullptr, nullptr, nullptr);
675 AioCompletion *my_completion_null = NULL;
676 ASSERT_NE(my_completion, my_completion_null);
677 bufferlist bl1;
678 ASSERT_EQ(0, test_data.m_ioctx.aio_read("nonexistent",
679 my_completion, &bl1, 128, 0));
680 {
681 TestAlarm alarm;
682 ASSERT_EQ(0, my_completion->wait_for_complete());
683 }
684 ASSERT_EQ(-ENOENT, my_completion->get_return_value());
685 delete my_completion;
686}
687
688TEST(LibRadosAio, FlushPP) {
689 AioTestDataPP test_data;
690 ASSERT_EQ("", test_data.init());
691 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
692 nullptr, nullptr, nullptr);
693 AioCompletion *my_completion_null = NULL;
694 ASSERT_NE(my_completion, my_completion_null);
695 char buf[128];
696 memset(buf, 0xee, sizeof(buf));
697 bufferlist bl1;
698 bl1.append(buf, sizeof(buf));
699 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
700 bl1, sizeof(buf), 0));
701 ASSERT_EQ(0, test_data.m_ioctx.aio_flush());
702 ASSERT_EQ(0, my_completion->get_return_value());
703 bufferlist bl2;
704 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
705 nullptr, nullptr, nullptr);
706 ASSERT_NE(my_completion2, my_completion_null);
707 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
708 &bl2, sizeof(buf), 0));
709 {
710 TestAlarm alarm;
711 ASSERT_EQ(0, my_completion2->wait_for_complete());
712 }
713 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
714 ASSERT_EQ(sizeof(buf), bl2.length());
715 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
716 delete my_completion;
717 delete my_completion2;
718}
719
720TEST(LibRadosAio, FlushAsyncPP) {
721 AioTestDataPP test_data;
722 ASSERT_EQ("", test_data.init());
723 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
724 nullptr, nullptr, nullptr);
725 AioCompletion *flush_completion =
726 test_data.m_cluster.aio_create_completion(NULL, NULL, NULL);
727 AioCompletion *my_completion_null = NULL;
728 ASSERT_NE(my_completion, my_completion_null);
729 char buf[128];
730 memset(buf, 0xee, sizeof(buf));
731 bufferlist bl1;
732 bl1.append(buf, sizeof(buf));
733 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
734 bl1, sizeof(buf), 0));
735 ASSERT_EQ(0, test_data.m_ioctx.aio_flush_async(flush_completion));
736 {
737 TestAlarm alarm;
738 ASSERT_EQ(0, flush_completion->wait_for_complete());
739 ASSERT_EQ(0, flush_completion->wait_for_safe());
740 }
741 ASSERT_EQ(1, my_completion->is_complete());
742 ASSERT_EQ(1, my_completion->is_safe());
743 ASSERT_EQ(1, flush_completion->is_complete());
744 ASSERT_EQ(1, flush_completion->is_safe());
745 ASSERT_EQ(0, my_completion->get_return_value());
746 bufferlist bl2;
747 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
748 nullptr, nullptr, nullptr);
749 ASSERT_NE(my_completion2, my_completion_null);
750 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
751 &bl2, sizeof(buf), 0));
752 {
753 TestAlarm alarm;
754 ASSERT_EQ(0, my_completion2->wait_for_complete());
755 }
756 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
757 ASSERT_EQ(sizeof(buf), bl2.length());
758 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
759 delete my_completion;
760 delete my_completion2;
761 delete flush_completion;
762}
763
764TEST(LibRadosAio, RoundTripWriteFullPP) {
765 AioTestDataPP test_data;
766 ASSERT_EQ("", test_data.init());
767 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
768 nullptr, nullptr, nullptr);
769 AioCompletion *my_completion_null = NULL;
770 ASSERT_NE(my_completion, my_completion_null);
771 char buf[128];
772 memset(buf, 0xcc, sizeof(buf));
773 bufferlist bl1;
774 bl1.append(buf, sizeof(buf));
775 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
776 bl1, sizeof(buf), 0));
777 {
778 TestAlarm alarm;
779 ASSERT_EQ(0, my_completion->wait_for_complete());
780 }
781 ASSERT_EQ(0, my_completion->get_return_value());
782 char buf2[64];
783 memset(buf2, 0xdd, sizeof(buf2));
784 bufferlist bl2;
785 bl2.append(buf2, sizeof(buf2));
786 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
787 nullptr, nullptr, nullptr);
788 ASSERT_NE(my_completion2, my_completion_null);
789 ASSERT_EQ(0, test_data.m_ioctx.aio_write_full("foo", my_completion2, bl2));
790 {
791 TestAlarm alarm;
792 ASSERT_EQ(0, my_completion2->wait_for_complete());
793 }
794 ASSERT_EQ(0, my_completion2->get_return_value());
795 bufferlist bl3;
796 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
797 nullptr, nullptr, nullptr);
798 ASSERT_NE(my_completion3, my_completion_null);
799 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion3,
800 &bl3, sizeof(buf), 0));
801 {
802 TestAlarm alarm;
803 ASSERT_EQ(0, my_completion3->wait_for_complete());
804 }
805 ASSERT_EQ((int)sizeof(buf2), my_completion3->get_return_value());
806 ASSERT_EQ(sizeof(buf2), bl3.length());
807 ASSERT_EQ(0, memcmp(bl3.c_str(), buf2, sizeof(buf2)));
808 delete my_completion;
809 delete my_completion2;
810 delete my_completion3;
811}
812
813//using ObjectWriteOperation/ObjectReadOperation with iohint
814TEST(LibRadosAio, RoundTripWriteFullPP2)
815{
816 Rados cluster;
817 std::string pool_name = get_temp_pool_name();
818 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
819 IoCtx ioctx;
820 cluster.ioctx_create(pool_name.c_str(), ioctx);
821
822 boost::scoped_ptr<AioCompletion> my_completion1(cluster.aio_create_completion(0, 0, 0));
823 ObjectWriteOperation op;
824 char buf[128];
825 memset(buf, 0xcc, sizeof(buf));
826 bufferlist bl;
827 bl.append(buf);
828
829 op.write_full(bl);
830 op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
831 ioctx.aio_operate("test_obj", my_completion1.get(), &op);
832 {
833 TestAlarm alarm;
834 ASSERT_EQ(0, my_completion1->wait_for_complete());
835 }
836 EXPECT_EQ(0, my_completion1->get_return_value());
837
838 boost::scoped_ptr<AioCompletion> my_completion2(cluster.aio_create_completion(0, 0, 0));
839 bl.clear();
840 ObjectReadOperation op1;
841 op1.read(0, sizeof(buf), &bl, NULL);
842 op1.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED|LIBRADOS_OP_FLAG_FADVISE_RANDOM);
843 ioctx.aio_operate("test_obj", my_completion2.get(), &op1, 0);
844 {
845 TestAlarm alarm;
846 ASSERT_EQ(0, my_completion2->wait_for_complete());
847 }
848 EXPECT_EQ(0, my_completion2->get_return_value());
849 ASSERT_EQ(0, memcmp(buf, bl.c_str(), sizeof(buf)));
850
851 ioctx.remove("test_obj");
852 destroy_one_pool_pp(pool_name, cluster);
853}
854
855TEST(LibRadosAio, RoundTripWriteSamePP) {
856 AioTestDataPP test_data;
857 ASSERT_EQ("", test_data.init());
858 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
859 nullptr, nullptr, nullptr);
860 AioCompletion *my_completion_null = NULL;
861 ASSERT_NE(my_completion, my_completion_null);
862 char full[128];
863 memset(full, 0xcc, sizeof(full));
864 bufferlist bl1;
865 bl1.append(full, sizeof(full));
866 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
867 bl1, sizeof(full), 0));
868 {
869 TestAlarm alarm;
870 ASSERT_EQ(0, my_completion->wait_for_complete());
871 }
872 ASSERT_EQ(0, my_completion->get_return_value());
873 /* write the same buf four times */
874 char buf[32];
875 size_t ws_write_len = sizeof(full);
876 memset(buf, 0xdd, sizeof(buf));
877 bufferlist bl2;
878 bl2.append(buf, sizeof(buf));
879 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
880 nullptr, nullptr, nullptr);
881 ASSERT_NE(my_completion2, my_completion_null);
882 ASSERT_EQ(0, test_data.m_ioctx.aio_writesame("foo", my_completion2, bl2,
883 ws_write_len, 0));
884 {
885 TestAlarm alarm;
886 ASSERT_EQ(0, my_completion2->wait_for_complete());
887 }
888 ASSERT_EQ(0, my_completion2->get_return_value());
889 bufferlist bl3;
890 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
891 nullptr, nullptr, nullptr);
892 ASSERT_NE(my_completion3, my_completion_null);
893 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion3,
894 &bl3, sizeof(full), 0));
895 {
896 TestAlarm alarm;
897 ASSERT_EQ(0, my_completion3->wait_for_complete());
898 }
899 ASSERT_EQ((int)sizeof(full), my_completion3->get_return_value());
900 ASSERT_EQ(sizeof(full), bl3.length());
901 for (char *cmp = bl3.c_str(); cmp < bl3.c_str() + bl3.length();
902 cmp += sizeof(buf)) {
903 ASSERT_EQ(0, memcmp(cmp, buf, sizeof(buf)));
904 }
905 delete my_completion;
906 delete my_completion2;
907 delete my_completion3;
908}
909
910TEST(LibRadosAio, RoundTripWriteSamePP2)
911{
912 Rados cluster;
913 std::string pool_name = get_temp_pool_name();
914 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
915 IoCtx ioctx;
916 cluster.ioctx_create(pool_name.c_str(), ioctx);
917
918 boost::scoped_ptr<AioCompletion>
919 wr_cmpl(cluster.aio_create_completion(0, 0, 0));
920 ObjectWriteOperation op;
921 char buf[128];
922 memset(buf, 0xcc, sizeof(buf));
923 bufferlist bl;
924 bl.append(buf, sizeof(buf));
925
926 op.writesame(0, sizeof(buf) * 4, bl);
927 op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
928 ioctx.aio_operate("test_obj", wr_cmpl.get(), &op);
929 {
930 TestAlarm alarm;
931 ASSERT_EQ(0, wr_cmpl->wait_for_complete());
932 }
933 EXPECT_EQ(0, wr_cmpl->get_return_value());
934
935 boost::scoped_ptr<AioCompletion>
936 rd_cmpl(cluster.aio_create_completion(0, 0, 0));
937 char *cmp;
938 char full[sizeof(buf) * 4];
939 memset(full, 0, sizeof(full));
940 bufferlist fl;
941 fl.append(full, sizeof(full));
942 ObjectReadOperation op1;
943 op1.read(0, sizeof(full), &fl, NULL);
944 op1.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
945 ioctx.aio_operate("test_obj", rd_cmpl.get(), &op1, 0);
946 {
947 TestAlarm alarm;
948 ASSERT_EQ(0, rd_cmpl->wait_for_complete());
949 }
950 EXPECT_EQ(0, rd_cmpl->get_return_value());
951 for (cmp = fl.c_str(); cmp < fl.c_str() + fl.length(); cmp += sizeof(buf)) {
952 ASSERT_EQ(0, memcmp(cmp, buf, sizeof(buf)));
953 }
954
955 ioctx.remove("test_obj");
956 destroy_one_pool_pp(pool_name, cluster);
957}
958
959TEST(LibRadosAio, SimpleStatPPNS) {
960 AioTestDataPP test_data;
961 ASSERT_EQ("", test_data.init());
962 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
963 nullptr, nullptr, nullptr);
964 AioCompletion *my_completion_null = NULL;
965 ASSERT_NE(my_completion, my_completion_null);
966 char buf[128];
967 memset(buf, 0xcc, sizeof(buf));
968 bufferlist bl1;
969 bl1.append(buf, sizeof(buf));
970 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
971 bl1, sizeof(buf), 0));
972 {
973 TestAlarm alarm;
974 ASSERT_EQ(0, my_completion->wait_for_complete());
975 }
976 ASSERT_EQ(0, my_completion->get_return_value());
977 uint64_t psize;
978 time_t pmtime;
979 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
980 nullptr, nullptr, nullptr);
981 ASSERT_NE(my_completion2, my_completion_null);
982 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion2,
983 &psize, &pmtime));
984 {
985 TestAlarm alarm;
986 ASSERT_EQ(0, my_completion2->wait_for_complete());
987 }
988 ASSERT_EQ(0, my_completion2->get_return_value());
989 ASSERT_EQ(sizeof(buf), psize);
990 delete my_completion;
991 delete my_completion2;
992}
993
994TEST(LibRadosAio, SimpleStatPP) {
995 AioTestDataPP test_data;
996 ASSERT_EQ("", test_data.init());
997 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
998 nullptr, nullptr, nullptr);
999 AioCompletion *my_completion_null = NULL;
1000 ASSERT_NE(my_completion, my_completion_null);
1001 char buf[128];
1002 memset(buf, 0xcc, sizeof(buf));
1003 bufferlist bl1;
1004 bl1.append(buf, sizeof(buf));
1005 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1006 bl1, sizeof(buf), 0));
1007 {
1008 TestAlarm alarm;
1009 ASSERT_EQ(0, my_completion->wait_for_complete());
1010 }
1011 ASSERT_EQ(0, my_completion->get_return_value());
1012 uint64_t psize;
1013 time_t pmtime;
1014 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1015 nullptr, nullptr, nullptr);
1016 ASSERT_NE(my_completion2, my_completion_null);
1017 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion2,
1018 &psize, &pmtime));
1019 {
1020 TestAlarm alarm;
1021 ASSERT_EQ(0, my_completion2->wait_for_complete());
1022 }
1023 ASSERT_EQ(0, my_completion2->get_return_value());
1024 ASSERT_EQ(sizeof(buf), psize);
1025 delete my_completion;
1026 delete my_completion2;
1027}
1028
1029TEST(LibRadosAio, StatRemovePP) {
1030 AioTestDataPP test_data;
1031 ASSERT_EQ("", test_data.init());
1032 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1033 nullptr, nullptr, nullptr);
1034 AioCompletion *my_completion_null = NULL;
1035 ASSERT_NE(my_completion, my_completion_null);
1036 char buf[128];
1037 memset(buf, 0xcc, sizeof(buf));
1038 bufferlist bl1;
1039 bl1.append(buf, sizeof(buf));
1040 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1041 bl1, sizeof(buf), 0));
1042 {
1043 TestAlarm alarm;
1044 ASSERT_EQ(0, my_completion->wait_for_complete());
1045 }
1046 ASSERT_EQ(0, my_completion->get_return_value());
1047 uint64_t psize;
1048 time_t pmtime;
1049 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1050 nullptr, nullptr, nullptr);
1051 ASSERT_NE(my_completion2, my_completion_null);
1052 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion2,
1053 &psize, &pmtime));
1054 {
1055 TestAlarm alarm;
1056 ASSERT_EQ(0, my_completion2->wait_for_complete());
1057 }
1058 ASSERT_EQ(0, my_completion2->get_return_value());
1059 ASSERT_EQ(sizeof(buf), psize);
1060 uint64_t psize2;
1061 time_t pmtime2;
1062 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
1063 nullptr, nullptr, nullptr);
1064 ASSERT_NE(my_completion3, my_completion_null);
1065 ASSERT_EQ(0, test_data.m_ioctx.aio_remove("foo", my_completion3));
1066 {
1067 TestAlarm alarm;
1068 ASSERT_EQ(0, my_completion3->wait_for_complete());
1069 }
1070 ASSERT_EQ(0, my_completion3->get_return_value());
1071
1072 AioCompletion *my_completion4 = test_data.m_cluster.aio_create_completion(
1073 nullptr, nullptr, nullptr);
1074 ASSERT_NE(my_completion4, my_completion_null);
1075 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion4,
1076 &psize2, &pmtime2));
1077 {
1078 TestAlarm alarm;
1079 ASSERT_EQ(0, my_completion4->wait_for_complete());
1080 }
1081 ASSERT_EQ(-ENOENT, my_completion4->get_return_value());
1082 delete my_completion;
1083 delete my_completion2;
1084 delete my_completion3;
1085 delete my_completion4;
1086}
1087
1088TEST(LibRadosAio, ExecuteClassPP) {
1089 AioTestDataPP test_data;
1090 ASSERT_EQ("", test_data.init());
1091 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1092 nullptr, nullptr, nullptr);
1093 AioCompletion *my_completion_null = NULL;
1094 ASSERT_NE(my_completion, my_completion_null);
1095 char buf[128];
1096 memset(buf, 0xcc, sizeof(buf));
1097 bufferlist bl1;
1098 bl1.append(buf, sizeof(buf));
1099 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1100 bl1, sizeof(buf), 0));
1101 {
1102 TestAlarm alarm;
1103 ASSERT_EQ(0, my_completion->wait_for_complete());
1104 }
1105 ASSERT_EQ(0, my_completion->get_return_value());
1106 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1107 nullptr, nullptr, nullptr);
1108 ASSERT_NE(my_completion2, my_completion_null);
1109 bufferlist in, out;
1110 ASSERT_EQ(0, test_data.m_ioctx.aio_exec("foo", my_completion2,
1111 "hello", "say_hello", in, &out));
1112 {
1113 TestAlarm alarm;
1114 ASSERT_EQ(0, my_completion2->wait_for_complete());
1115 }
1116 ASSERT_EQ(0, my_completion2->get_return_value());
1117 ASSERT_EQ(std::string("Hello, world!"), std::string(out.c_str(), out.length()));
1118 delete my_completion;
1119 delete my_completion2;
1120}
1121
1122using std::string;
1123using std::map;
1124using std::set;
1125
1126TEST(LibRadosAio, OmapPP) {
1127 Rados cluster;
1128 std::string pool_name = get_temp_pool_name();
1129 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
1130 IoCtx ioctx;
1131 cluster.ioctx_create(pool_name.c_str(), ioctx);
1132
1133 string header_str = "baz";
1134 bufferptr bp(header_str.c_str(), header_str.size() + 1);
1135 bufferlist header_to_set;
1136 header_to_set.push_back(bp);
1137 map<string, bufferlist> to_set;
1138 {
1139 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
1140 ObjectWriteOperation op;
1141 to_set["foo"] = header_to_set;
1142 to_set["foo2"] = header_to_set;
1143 to_set["qfoo3"] = header_to_set;
1144 op.omap_set(to_set);
1145
1146 op.omap_set_header(header_to_set);
1147
1148 ioctx.aio_operate("test_obj", my_completion.get(), &op);
1149 {
1150 TestAlarm alarm;
1151 ASSERT_EQ(0, my_completion->wait_for_complete());
1152 }
1153 EXPECT_EQ(0, my_completion->get_return_value());
1154 }
1155
1156 {
1157 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
1158 ObjectReadOperation op;
1159 map<string, pair<bufferlist, int> > assertions;
1160 bufferlist val;
1161 val.append(string("bar"));
1162 assertions["foo"] = pair<bufferlist, int>(val, CEPH_OSD_CMPXATTR_OP_EQ);
1163
1164 int r;
1165 op.omap_cmp(assertions, &r);
1166
1167 ioctx.aio_operate("test_obj", my_completion.get(), &op, 0);
1168 {
1169 TestAlarm alarm;
1170 ASSERT_EQ(0, my_completion->wait_for_complete());
1171 }
1172 EXPECT_EQ(-ECANCELED, my_completion->get_return_value());
1173 ASSERT_EQ(-ECANCELED, r);
1174 }
1175
1176 {
1177 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
1178 ObjectReadOperation op;
1179
1180 set<string> set_got;
1181 map<string, bufferlist> map_got;
1182
1183 set<string> to_get;
1184 map<string, bufferlist> got3;
1185
1186 map<string, bufferlist> got4;
1187
1188 bufferlist header;
1189
1190 op.omap_get_keys2("", 1, &set_got, nullptr, 0);
1191 op.omap_get_vals2("foo", 1, &map_got, nullptr, 0);
1192
1193 to_get.insert("foo");
1194 to_get.insert("qfoo3");
1195 op.omap_get_vals_by_keys(to_get, &got3, 0);
1196
1197 op.omap_get_header(&header, 0);
1198
1199 op.omap_get_vals2("foo2", "q", 1, &got4, nullptr, 0);
1200
1201 ioctx.aio_operate("test_obj", my_completion.get(), &op, 0);
1202 {
1203 TestAlarm alarm;
1204 ASSERT_EQ(0, my_completion->wait_for_complete());
1205 }
1206 EXPECT_EQ(0, my_completion->get_return_value());
1207
1208 ASSERT_EQ(header.length(), header_to_set.length());
1209 ASSERT_EQ(set_got.size(), (unsigned)1);
1210 ASSERT_EQ(*set_got.begin(), "foo");
1211 ASSERT_EQ(map_got.size(), (unsigned)1);
1212 ASSERT_EQ(map_got.begin()->first, "foo2");
1213 ASSERT_EQ(got3.size(), (unsigned)2);
1214 ASSERT_EQ(got3.begin()->first, "foo");
1215 ASSERT_EQ(got3.rbegin()->first, "qfoo3");
1216 ASSERT_EQ(got4.size(), (unsigned)1);
1217 ASSERT_EQ(got4.begin()->first, "qfoo3");
1218 }
1219
1220 {
1221 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
1222 ObjectWriteOperation op;
1223 set<string> to_remove;
1224 to_remove.insert("foo2");
1225 op.omap_rm_keys(to_remove);
1226 ioctx.aio_operate("test_obj", my_completion.get(), &op);
1227 {
1228 TestAlarm alarm;
1229 ASSERT_EQ(0, my_completion->wait_for_complete());
1230 }
1231 EXPECT_EQ(0, my_completion->get_return_value());
1232 }
1233
1234 {
1235 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
1236 ObjectReadOperation op;
1237
1238 set<string> set_got;
1239 op.omap_get_keys2("", -1, &set_got, nullptr, 0);
1240 ioctx.aio_operate("test_obj", my_completion.get(), &op, 0);
1241 {
1242 TestAlarm alarm;
1243 ASSERT_EQ(0, my_completion->wait_for_complete());
1244 }
1245 EXPECT_EQ(0, my_completion->get_return_value());
1246 ASSERT_EQ(set_got.size(), (unsigned)2);
1247 }
1248
1249 {
1250 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
1251 ObjectWriteOperation op;
1252 op.omap_clear();
1253 ioctx.aio_operate("test_obj", my_completion.get(), &op);
1254 {
1255 TestAlarm alarm;
1256 ASSERT_EQ(0, my_completion->wait_for_complete());
1257 }
1258 EXPECT_EQ(0, my_completion->get_return_value());
1259 }
1260
1261 {
1262 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
1263 ObjectReadOperation op;
1264
1265 set<string> set_got;
1266 op.omap_get_keys2("", -1, &set_got, nullptr, 0);
1267 ioctx.aio_operate("test_obj", my_completion.get(), &op, 0);
1268 {
1269 TestAlarm alarm;
1270 ASSERT_EQ(0, my_completion->wait_for_complete());
1271 }
1272 EXPECT_EQ(0, my_completion->get_return_value());
1273 ASSERT_EQ(set_got.size(), (unsigned)0);
1274 }
1275
1276 // omap_clear clears header *and* keys
1277 {
1278 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
1279 ObjectWriteOperation op;
1280 bufferlist bl;
1281 bl.append("some data");
1282 map<string,bufferlist> to_set;
1283 to_set["foo"] = bl;
1284 to_set["foo2"] = bl;
1285 to_set["qfoo3"] = bl;
1286 op.omap_set(to_set);
1287 op.omap_set_header(bl);
1288 ioctx.aio_operate("foo3", my_completion.get(), &op);
1289 {
1290 TestAlarm alarm;
1291 ASSERT_EQ(0, my_completion->wait_for_complete());
1292 }
1293 EXPECT_EQ(0, my_completion->get_return_value());
1294 }
1295 {
1296 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
1297 ObjectWriteOperation op;
1298 op.omap_clear();
1299 ioctx.aio_operate("foo3", my_completion.get(), &op);
1300 {
1301 TestAlarm alarm;
1302 ASSERT_EQ(0, my_completion->wait_for_complete());
1303 }
1304 EXPECT_EQ(0, my_completion->get_return_value());
1305 }
1306 {
1307 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
1308 ObjectReadOperation op;
1309 set<string> set_got;
1310 bufferlist hdr;
1311 op.omap_get_keys2("", -1, &set_got, nullptr, 0);
1312 op.omap_get_header(&hdr, NULL);
1313 ioctx.aio_operate("foo3", my_completion.get(), &op, 0);
1314 {
1315 TestAlarm alarm;
1316 ASSERT_EQ(0, my_completion->wait_for_complete());
1317 }
1318 EXPECT_EQ(0, my_completion->get_return_value());
1319 ASSERT_EQ(set_got.size(), (unsigned)0);
1320 ASSERT_EQ(hdr.length(), 0u);
1321 }
1322
1323 ioctx.remove("test_obj");
1324 destroy_one_pool_pp(pool_name, cluster);
1325}
1326
1327TEST(LibRadosAio, MultiWritePP) {
1328 AioTestDataPP test_data;
1329 ASSERT_EQ("", test_data.init());
1330 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1331 nullptr, nullptr, nullptr);
1332 AioCompletion *my_completion_null = NULL;
1333 ASSERT_NE(my_completion, my_completion_null);
1334 char buf[128];
1335 memset(buf, 0xcc, sizeof(buf));
1336 bufferlist bl1;
1337 bl1.append(buf, sizeof(buf));
1338 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1339 bl1, sizeof(buf), 0));
1340 {
1341 TestAlarm alarm;
1342 ASSERT_EQ(0, my_completion->wait_for_complete());
1343 }
1344 ASSERT_EQ(0, my_completion->get_return_value());
1345
1346 char buf2[64];
1347 memset(buf2, 0xdd, sizeof(buf2));
1348 bufferlist bl2;
1349 bl2.append(buf2, sizeof(buf2));
1350 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1351 nullptr, nullptr, nullptr);
1352 ASSERT_NE(my_completion2, my_completion_null);
1353 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion2,
1354 bl2, sizeof(buf2), sizeof(buf)));
1355 {
1356 TestAlarm alarm;
1357 ASSERT_EQ(0, my_completion2->wait_for_complete());
1358 }
1359 ASSERT_EQ(0, my_completion2->get_return_value());
1360
1361 bufferlist bl3;
1362 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
1363 nullptr, nullptr, nullptr);
1364 ASSERT_NE(my_completion3, my_completion_null);
1365 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion3,
1366 &bl3, (sizeof(buf) + sizeof(buf2) * 3), 0));
1367 {
1368 TestAlarm alarm;
1369 ASSERT_EQ(0, my_completion3->wait_for_complete());
1370 }
1371 ASSERT_EQ((int)(sizeof(buf) + sizeof(buf2)), my_completion3->get_return_value());
1372 ASSERT_EQ(sizeof(buf) + sizeof(buf2), bl3.length());
1373 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
1374 ASSERT_EQ(0, memcmp(bl3.c_str() + sizeof(buf), buf2, sizeof(buf2)));
1375 delete my_completion;
1376 delete my_completion2;
1377 delete my_completion3;
1378}
1379
1380TEST(LibRadosAio, AioUnlockPP) {
1381 AioTestDataPP test_data;
1382 ASSERT_EQ("", test_data.init());
1383 ASSERT_EQ(0, test_data.m_ioctx.lock_exclusive("foo", "TestLock", "Cookie", "", NULL, 0));
1384 boost::scoped_ptr<AioCompletion> my_completion
1385 (test_data.m_cluster.aio_create_completion
1386 (nullptr, nullptr, nullptr));
1387 ASSERT_EQ(0, test_data.m_ioctx.aio_unlock("foo", "TestLock", "Cookie", my_completion.get()));
1388 {
1389 TestAlarm alarm;
1390 ASSERT_EQ(0, my_completion->wait_for_complete());
1391 }
1392 ASSERT_EQ(0, my_completion->get_return_value());
1393 bufferlist bl2;
1394 ASSERT_EQ(0, test_data.m_ioctx.lock_exclusive("foo", "TestLock", "Cookie", "", NULL, 0));
1395}
1396
1397class AioTestDataECPP
1398{
1399public:
1400 AioTestDataECPP()
1401 : m_init(false)
1402 {}
1403
1404 ~AioTestDataECPP()
1405 {
1406 if (m_init) {
1407 m_ioctx.close();
1408 destroy_one_ec_pool_pp(m_pool_name, m_cluster);
1409 }
1410 }
1411
1412 std::string init()
1413 {
1414 int ret;
1415 m_pool_name = get_temp_pool_name();
1416 std::string err = create_one_ec_pool_pp(m_pool_name, m_cluster);
1417 if (!err.empty()) {
1418 ostringstream oss;
1419 oss << "create_one_ec_pool(" << m_pool_name << ") failed: error " << err;
1420 return oss.str();
1421 }
1422 ret = m_cluster.ioctx_create(m_pool_name.c_str(), m_ioctx);
1423 if (ret) {
1424 destroy_one_ec_pool_pp(m_pool_name, m_cluster);
1425 ostringstream oss;
1426 oss << "rados_ioctx_create failed: error " << ret;
1427 return oss.str();
1428 }
1429 m_init = true;
1430 return "";
1431 }
1432
1433 Rados m_cluster;
1434 IoCtx m_ioctx;
1435 std::string m_pool_name;
1436 bool m_init;
1437};
1438
1439// EC test cases
1440TEST(LibRadosAioEC, SimpleWritePP) {
1441 char buf[128];
1442 memset(buf, 0xcc, sizeof(buf));
1443 bufferlist bl1;
1444 bl1.append(buf, sizeof(buf));
1445 {
1446 AioTestDataECPP test_data;
1447 ASSERT_EQ("", test_data.init());
1448 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1449 nullptr, nullptr, nullptr);
1450 AioCompletion *my_completion_null = NULL;
1451 ASSERT_NE(my_completion, my_completion_null);
1452 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
1453 my_completion, bl1, sizeof(buf), 0));
1454 {
1455 TestAlarm alarm;
1456 ASSERT_EQ(0, my_completion->wait_for_complete());
1457 }
1458 ASSERT_EQ(0, my_completion->get_return_value());
1459 delete my_completion;
1460 }
1461
1462 {
1463 AioTestDataECPP test_data;
1464 ASSERT_EQ("", test_data.init());
1465 test_data.m_ioctx.set_namespace("nspace");
1466 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1467 nullptr, nullptr, nullptr);
1468 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
1469 my_completion, bl1, sizeof(buf), 0));
1470 {
1471 TestAlarm alarm;
1472 ASSERT_EQ(0, my_completion->wait_for_complete());
1473 }
1474 ASSERT_EQ(0, my_completion->get_return_value());
1475 delete my_completion;
1476 }
1477}
1478
1479TEST(LibRadosAioEC, WaitForSafePP) {
1480 AioTestDataECPP test_data;
1481 ASSERT_EQ("", test_data.init());
1482 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1483 nullptr, nullptr, nullptr);
1484 AioCompletion *my_completion_null = NULL;
1485 ASSERT_NE(my_completion, my_completion_null);
1486 char buf[128];
1487 memset(buf, 0xcc, sizeof(buf));
1488 bufferlist bl1;
1489 bl1.append(buf, sizeof(buf));
1490 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo",
1491 my_completion, bl1, sizeof(buf), 0));
1492 TestAlarm alarm;
1493 ASSERT_EQ(0, my_completion->wait_for_safe());
1494 ASSERT_EQ(0, my_completion->get_return_value());
1495 delete my_completion;
1496}
1497
1498TEST(LibRadosAioEC, RoundTripPP) {
1499 AioTestDataECPP test_data;
1500 ASSERT_EQ("", test_data.init());
1501 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1502 nullptr, nullptr, nullptr);
1503 AioCompletion *my_completion_null = NULL;
1504 ASSERT_NE(my_completion, my_completion_null);
1505 char buf[128];
1506 memset(buf, 0xcc, sizeof(buf));
1507 bufferlist bl1;
1508 bl1.append(buf, sizeof(buf));
1509 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1510 bl1, sizeof(buf), 0));
1511 {
1512 TestAlarm alarm;
1513 ASSERT_EQ(0, my_completion->wait_for_complete());
1514 }
1515 ASSERT_EQ(0, my_completion->get_return_value());
1516 bufferlist bl2;
1517 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1518 nullptr, nullptr, nullptr);
1519 ASSERT_NE(my_completion2, my_completion_null);
1520 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo",
1521 my_completion2, &bl2, sizeof(buf), 0));
1522 {
1523 TestAlarm alarm;
1524 ASSERT_EQ(0, my_completion2->wait_for_complete());
1525 }
1526 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
1527 ASSERT_EQ(sizeof(buf), bl2.length());
1528 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
1529 delete my_completion;
1530 delete my_completion2;
1531}
1532
1533TEST(LibRadosAioEC, RoundTripPP2) {
1534 AioTestDataECPP test_data;
1535 ASSERT_EQ("", test_data.init());
1536 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1537 nullptr, nullptr, nullptr);
1538 AioCompletion *my_completion_null = NULL;
1539 ASSERT_NE(my_completion, my_completion_null);
1540 char buf[128];
1541 memset(buf, 0xcc, sizeof(buf));
1542 bufferlist bl1;
1543 bl1.append(buf, sizeof(buf));
1544 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1545 bl1, sizeof(buf), 0));
1546 {
1547 TestAlarm alarm;
1548 ASSERT_EQ(0, my_completion->wait_for_complete());
1549 }
1550 ASSERT_EQ(0, my_completion->get_return_value());
1551 bufferlist bl2;
1552 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1553 nullptr, nullptr, nullptr);
1554 ASSERT_NE(my_completion2, my_completion_null);
1555 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo",
1556 my_completion2, &bl2, sizeof(buf), 0));
1557 {
1558 TestAlarm alarm;
1559 ASSERT_EQ(0, my_completion2->wait_for_safe());
1560 ASSERT_EQ(0, my_completion2->wait_for_complete());
1561 }
1562 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
1563 ASSERT_EQ(sizeof(buf), bl2.length());
1564 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
1565 delete my_completion;
1566 delete my_completion2;
1567}
1568
1569//using ObjectWriteOperation/ObjectReadOperation with iohint
1570TEST(LibRadosAioEC, RoundTripPP3)
1571{
1572 Rados cluster;
1573 std::string pool_name = get_temp_pool_name();
1574 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
1575 IoCtx ioctx;
1576 cluster.ioctx_create(pool_name.c_str(), ioctx);
1577
1578 boost::scoped_ptr<AioCompletion> my_completion1(cluster.aio_create_completion(0, 0, 0));
1579 ObjectWriteOperation op;
1580 char buf[128];
1581 memset(buf, 0xcc, sizeof(buf));
1582 bufferlist bl;
1583 bl.append(buf);
1584
1585 op.write(0, bl);
1586 op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
1587 ioctx.aio_operate("test_obj", my_completion1.get(), &op);
1588 {
1589 TestAlarm alarm;
1590 ASSERT_EQ(0, my_completion1->wait_for_complete());
1591 }
1592 EXPECT_EQ(0, my_completion1->get_return_value());
1593
1594 boost::scoped_ptr<AioCompletion> my_completion2(cluster.aio_create_completion(0, 0, 0));
1595 bl.clear();
1596 ObjectReadOperation op1;
1597 op1.read(0, sizeof(buf), &bl, NULL);
1598 op1.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED|LIBRADOS_OP_FLAG_FADVISE_RANDOM);
1599 ioctx.aio_operate("test_obj", my_completion2.get(), &op1, 0);
1600 {
1601 TestAlarm alarm;
1602 ASSERT_EQ(0, my_completion2->wait_for_complete());
1603 }
1604 EXPECT_EQ(0, my_completion2->get_return_value());
1605 ASSERT_EQ(0, memcmp(buf, bl.c_str(), sizeof(buf)));
1606
1607 ioctx.remove("test_obj");
1608 destroy_one_pool_pp(pool_name, cluster);
1609}
1610
1611TEST(LibRadosAio, RoundTripAppendPP) {
1612 AioTestDataPP test_data;
1613 ASSERT_EQ("", test_data.init());
1614 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1615 nullptr, nullptr, nullptr);
1616 AioCompletion *my_completion_null = NULL;
1617 ASSERT_NE(my_completion, my_completion_null);
1618 char buf[128];
1619 memset(buf, 0xcc, sizeof(buf));
1620 bufferlist bl1;
1621 bl1.append(buf, sizeof(buf));
1622 ASSERT_EQ(0, test_data.m_ioctx.aio_append("foo", my_completion,
1623 bl1, sizeof(buf)));
1624 {
1625 TestAlarm alarm;
1626 ASSERT_EQ(0, my_completion->wait_for_complete());
1627 }
1628 ASSERT_EQ(0, my_completion->get_return_value());
1629 char buf2[128];
1630 memset(buf2, 0xdd, sizeof(buf2));
1631 bufferlist bl2;
1632 bl2.append(buf2, sizeof(buf2));
1633 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1634 nullptr, nullptr, nullptr);
1635 ASSERT_NE(my_completion2, my_completion_null);
1636 ASSERT_EQ(0, test_data.m_ioctx.aio_append("foo", my_completion2,
1637 bl2, sizeof(buf2)));
1638 {
1639 TestAlarm alarm;
1640 ASSERT_EQ(0, my_completion2->wait_for_complete());
1641 }
1642 ASSERT_EQ(0, my_completion2->get_return_value());
1643 bufferlist bl3;
1644 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
1645 nullptr, nullptr, nullptr);
1646 ASSERT_NE(my_completion3, my_completion_null);
1647 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo",
1648 my_completion3, &bl3, 2 * sizeof(buf), 0));
1649 {
1650 TestAlarm alarm;
1651 ASSERT_EQ(0, my_completion3->wait_for_complete());
1652 }
1653 ASSERT_EQ((int)(sizeof(buf) * 2), my_completion3->get_return_value());
1654 ASSERT_EQ(sizeof(buf) * 2, bl3.length());
1655 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
1656 ASSERT_EQ(0, memcmp(bl3.c_str() + sizeof(buf), buf2, sizeof(buf2)));
1657 delete my_completion;
1658 delete my_completion2;
1659 delete my_completion3;
1660}
1661
1662TEST(LibRadosAioPP, RemoveTestPP) {
1663 char buf[128];
1664 memset(buf, 0xaa, sizeof(buf));
1665 bufferlist bl1;
1666 bl1.append(buf, sizeof(buf));
1667 AioTestDataPP test_data;
1668 ASSERT_EQ("", test_data.init());
1669 ASSERT_EQ(0, test_data.m_ioctx.append("foo", bl1, sizeof(buf)));
1670 boost::scoped_ptr<AioCompletion> my_completion
1671 (test_data.m_cluster.aio_create_completion
1672 (nullptr, nullptr, nullptr));
1673 ASSERT_EQ(0, test_data.m_ioctx.aio_remove("foo", my_completion.get()));
1674 {
1675 TestAlarm alarm;
1676 ASSERT_EQ(0, my_completion->wait_for_complete());
1677 }
1678 ASSERT_EQ(0, my_completion->get_return_value());
1679 bufferlist bl2;
1680 ASSERT_EQ(-ENOENT, test_data.m_ioctx.read("foo", bl2, sizeof(buf), 0));
1681}
1682
1683TEST(LibRadosAioEC, RoundTripSparseReadPP) {
1684 AioTestDataECPP test_data;
1685 ASSERT_EQ("", test_data.init());
1686 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1687 nullptr, nullptr, nullptr);
1688 AioCompletion *my_completion_null = NULL;
1689 ASSERT_NE(my_completion, my_completion_null);
1690 char buf[128];
1691 memset(buf, 0xcc, sizeof(buf));
1692 bufferlist bl1;
1693 bl1.append(buf, sizeof(buf));
1694 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1695 bl1, sizeof(buf), 0));
1696 {
1697 TestAlarm alarm;
1698 ASSERT_EQ(0, my_completion->wait_for_complete());
1699 }
1700 ASSERT_EQ(0, my_completion->get_return_value());
1701
1702 map<uint64_t, uint64_t> extents;
1703 bufferlist bl2;
1704 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1705 nullptr, nullptr, nullptr);
1706 ASSERT_NE(my_completion2, my_completion_null);
1707 ASSERT_EQ(0, test_data.m_ioctx.aio_sparse_read("foo",
1708 my_completion2, &extents, &bl2, sizeof(buf), 0));
1709 {
1710 TestAlarm alarm;
1711 ASSERT_EQ(0, my_completion2->wait_for_complete());
1712 }
1713 ASSERT_EQ(0, my_completion2->get_return_value());
1714 assert_eq_sparse(bl1, extents, bl2);
1715 delete my_completion;
1716 delete my_completion2;
1717}
1718
1719TEST(LibRadosAioEC, RoundTripAppendPP) {
1720 AioTestDataECPP test_data;
1721 ASSERT_EQ("", test_data.init());
1722 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1723 nullptr, nullptr, nullptr);
1724 AioCompletion *my_completion_null = NULL;
1725 ASSERT_NE(my_completion, my_completion_null);
1726 bool requires;
1727 ASSERT_EQ(0, test_data.m_ioctx.pool_requires_alignment2(&requires));
1728 ASSERT_TRUE(requires);
1729 uint64_t alignment;
1730 ASSERT_EQ(0, test_data.m_ioctx.pool_required_alignment2(&alignment));
1731 ASSERT_NE((unsigned)0, alignment);
1732 int bsize = alignment;
1733 char *buf = (char *)new char[bsize];
1734 memset(buf, 0xcc, bsize);
1735 bufferlist bl1;
1736 bl1.append(buf, bsize);
1737 ASSERT_EQ(0, test_data.m_ioctx.aio_append("foo", my_completion,
1738 bl1, bsize));
1739 {
1740 TestAlarm alarm;
1741 ASSERT_EQ(0, my_completion->wait_for_complete());
1742 }
1743 ASSERT_EQ(0, my_completion->get_return_value());
1744
1745 int hbsize = bsize / 2;
1746 char *buf2 = (char *)new char[hbsize];
1747 memset(buf2, 0xdd, hbsize);
1748 bufferlist bl2;
1749 bl2.append(buf2, hbsize);
1750 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1751 nullptr, nullptr, nullptr);
1752 ASSERT_NE(my_completion2, my_completion_null);
1753 ASSERT_EQ(0, test_data.m_ioctx.aio_append("foo", my_completion2,
1754 bl2, hbsize));
1755 {
1756 TestAlarm alarm;
1757 ASSERT_EQ(0, my_completion2->wait_for_complete());
1758 }
1759 ASSERT_EQ(0, my_completion2->get_return_value());
1760
1761 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
1762 nullptr, nullptr, nullptr);
1763 ASSERT_NE(my_completion3, my_completion_null);
1764 ASSERT_EQ(0, test_data.m_ioctx.aio_append("foo", my_completion3,
1765 bl2, hbsize));
1766 {
1767 TestAlarm alarm;
1768 ASSERT_EQ(0, my_completion3->wait_for_complete());
1769 }
1770 EXPECT_EQ(-EOPNOTSUPP, my_completion3->get_return_value());
1771
1772 bufferlist bl3;
1773 AioCompletion *my_completion4 = test_data.m_cluster.aio_create_completion(
1774 nullptr, nullptr, nullptr);
1775 ASSERT_NE(my_completion4, my_completion_null);
1776 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo",
1777 my_completion4, &bl3, bsize * 3, 0));
1778 {
1779 TestAlarm alarm;
1780 ASSERT_EQ(0, my_completion4->wait_for_complete());
1781 }
1782 int tbsize = bsize + hbsize;
1783 ASSERT_EQ(tbsize, my_completion4->get_return_value());
1784 ASSERT_EQ((unsigned)tbsize, bl3.length());
1785 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, bsize));
1786 ASSERT_EQ(0, memcmp(bl3.c_str() + bsize, buf2, hbsize));
1787 delete my_completion;
1788 delete my_completion2;
1789 delete my_completion3;
1790 delete[] buf;
1791 delete[] buf2;
1792}
1793
1794TEST(LibRadosAioEC, IsCompletePP) {
1795 AioTestDataECPP test_data;
1796 ASSERT_EQ("", test_data.init());
1797 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1798 nullptr, nullptr, nullptr);
1799 AioCompletion *my_completion_null = NULL;
1800 ASSERT_NE(my_completion, my_completion_null);
1801 char buf[128];
1802 memset(buf, 0xcc, sizeof(buf));
1803 bufferlist bl1;
1804 bl1.append(buf, sizeof(buf));
1805 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1806 bl1, sizeof(buf), 0));
1807 {
1808 TestAlarm alarm;
1809 ASSERT_EQ(0, my_completion->wait_for_complete());
1810 }
1811 ASSERT_EQ(0, my_completion->get_return_value());
1812 bufferlist bl2;
1813 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1814 nullptr, nullptr, nullptr);
1815 ASSERT_NE(my_completion2, my_completion_null);
1816 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
1817 &bl2, sizeof(buf), 0));
1818 {
1819 TestAlarm alarm;
1820
1821 // Busy-wait until the AIO completes.
1822 // Normally we wouldn't do this, but we want to test is_complete.
1823 while (true) {
1824 int is_complete = my_completion2->is_complete();
1825 if (is_complete)
1826 break;
1827 }
1828 }
1829 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
1830 ASSERT_EQ(sizeof(buf), bl2.length());
1831 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
1832 delete my_completion;
1833 delete my_completion2;
1834}
1835TEST(LibRadosAioEC, IsSafePP) {
1836 AioTestDataECPP test_data;
1837 ASSERT_EQ("", test_data.init());
1838 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1839 nullptr, nullptr, nullptr);
1840 AioCompletion *my_completion_null = NULL;
1841 ASSERT_NE(my_completion, my_completion_null);
1842 char buf[128];
1843 memset(buf, 0xcc, sizeof(buf));
1844 bufferlist bl1;
1845 bl1.append(buf, sizeof(buf));
1846 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1847 bl1, sizeof(buf), 0));
1848 {
1849 TestAlarm alarm;
1850
1851 // Busy-wait until the AIO completes.
1852 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
1853 while (true) {
1854 int is_safe = my_completion->is_safe();
1855 if (is_safe)
1856 break;
1857 }
1858 }
1859 ASSERT_EQ(0, my_completion->get_return_value());
1860 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1861 nullptr, nullptr, nullptr);
1862 bufferlist bl2;
1863 ASSERT_NE(my_completion2, my_completion_null);
1864 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
1865 &bl2, sizeof(buf), 0));
1866 {
1867 TestAlarm alarm;
1868 ASSERT_EQ(0, my_completion2->wait_for_complete());
1869 }
1870 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
1871 ASSERT_EQ(sizeof(buf), bl2.length());
1872 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
1873 delete my_completion;
1874 delete my_completion2;
1875}
1876
1877TEST(LibRadosAioEC, ReturnValuePP) {
1878 AioTestDataECPP test_data;
1879 ASSERT_EQ("", test_data.init());
1880 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1881 nullptr, nullptr, nullptr);
1882 AioCompletion *my_completion_null = NULL;
1883 ASSERT_NE(my_completion, my_completion_null);
1884 bufferlist bl1;
1885 ASSERT_EQ(0, test_data.m_ioctx.aio_read("nonexistent",
1886 my_completion, &bl1, 128, 0));
1887 {
1888 TestAlarm alarm;
1889 ASSERT_EQ(0, my_completion->wait_for_complete());
1890 }
1891 ASSERT_EQ(-ENOENT, my_completion->get_return_value());
1892 delete my_completion;
1893}
1894
1895TEST(LibRadosAioEC, FlushPP) {
1896 AioTestDataECPP test_data;
1897 ASSERT_EQ("", test_data.init());
1898 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1899 nullptr, nullptr, nullptr);
1900 AioCompletion *my_completion_null = NULL;
1901 ASSERT_NE(my_completion, my_completion_null);
1902 char buf[128];
1903 memset(buf, 0xee, sizeof(buf));
1904 bufferlist bl1;
1905 bl1.append(buf, sizeof(buf));
1906 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1907 bl1, sizeof(buf), 0));
1908 ASSERT_EQ(0, test_data.m_ioctx.aio_flush());
1909 ASSERT_EQ(0, my_completion->get_return_value());
1910 bufferlist bl2;
1911 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1912 nullptr, nullptr, nullptr);
1913 ASSERT_NE(my_completion2, my_completion_null);
1914 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
1915 &bl2, sizeof(buf), 0));
1916 {
1917 TestAlarm alarm;
1918 ASSERT_EQ(0, my_completion2->wait_for_complete());
1919 }
1920 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
1921 ASSERT_EQ(sizeof(buf), bl2.length());
1922 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
1923 delete my_completion;
1924 delete my_completion2;
1925}
1926
1927TEST(LibRadosAioEC, FlushAsyncPP) {
1928 AioTestDataECPP test_data;
1929 ASSERT_EQ("", test_data.init());
1930 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1931 nullptr, nullptr, nullptr);
1932 AioCompletion *flush_completion =
1933 test_data.m_cluster.aio_create_completion(NULL, NULL, NULL);
1934 AioCompletion *my_completion_null = NULL;
1935 ASSERT_NE(my_completion, my_completion_null);
1936 char buf[128];
1937 memset(buf, 0xee, 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 ASSERT_EQ(0, test_data.m_ioctx.aio_flush_async(flush_completion));
1943 {
1944 TestAlarm alarm;
1945 ASSERT_EQ(0, flush_completion->wait_for_complete());
1946 ASSERT_EQ(0, flush_completion->wait_for_safe());
1947 }
1948 ASSERT_EQ(1, my_completion->is_complete());
1949 ASSERT_EQ(1, my_completion->is_safe());
1950 ASSERT_EQ(1, flush_completion->is_complete());
1951 ASSERT_EQ(1, flush_completion->is_safe());
1952 ASSERT_EQ(0, my_completion->get_return_value());
1953 bufferlist bl2;
1954 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1955 nullptr, nullptr, nullptr);
1956 ASSERT_NE(my_completion2, my_completion_null);
1957 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion2,
1958 &bl2, sizeof(buf), 0));
1959 {
1960 TestAlarm alarm;
1961 ASSERT_EQ(0, my_completion2->wait_for_complete());
1962 }
1963 ASSERT_EQ((int)sizeof(buf), my_completion2->get_return_value());
1964 ASSERT_EQ(sizeof(buf), bl2.length());
1965 ASSERT_EQ(0, memcmp(buf, bl2.c_str(), sizeof(buf)));
1966 delete my_completion;
1967 delete my_completion2;
1968 delete flush_completion;
1969}
1970
1971TEST(LibRadosAioEC, RoundTripWriteFullPP) {
1972 AioTestDataECPP test_data;
1973 ASSERT_EQ("", test_data.init());
1974 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
1975 nullptr, nullptr, nullptr);
1976 AioCompletion *my_completion_null = NULL;
1977 ASSERT_NE(my_completion, my_completion_null);
1978 char buf[128];
1979 memset(buf, 0xcc, sizeof(buf));
1980 bufferlist bl1;
1981 bl1.append(buf, sizeof(buf));
1982 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
1983 bl1, sizeof(buf), 0));
1984 {
1985 TestAlarm alarm;
1986 ASSERT_EQ(0, my_completion->wait_for_complete());
1987 }
1988 ASSERT_EQ(0, my_completion->get_return_value());
1989 char buf2[64];
1990 memset(buf2, 0xdd, sizeof(buf2));
1991 bufferlist bl2;
1992 bl2.append(buf2, sizeof(buf2));
1993 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
1994 nullptr, nullptr, nullptr);
1995 ASSERT_NE(my_completion2, my_completion_null);
1996 ASSERT_EQ(0, test_data.m_ioctx.aio_write_full("foo", my_completion2, bl2));
1997 {
1998 TestAlarm alarm;
1999 ASSERT_EQ(0, my_completion2->wait_for_complete());
2000 }
2001 ASSERT_EQ(0, my_completion2->get_return_value());
2002 bufferlist bl3;
2003 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
2004 nullptr, nullptr, nullptr);
2005 ASSERT_NE(my_completion3, my_completion_null);
2006 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion3,
2007 &bl3, sizeof(buf), 0));
2008 {
2009 TestAlarm alarm;
2010 ASSERT_EQ(0, my_completion3->wait_for_complete());
2011 }
2012 ASSERT_EQ((int)sizeof(buf2), my_completion3->get_return_value());
2013 ASSERT_EQ(sizeof(buf2), bl3.length());
2014 ASSERT_EQ(0, memcmp(bl3.c_str(), buf2, sizeof(buf2)));
2015 delete my_completion;
2016 delete my_completion2;
2017 delete my_completion3;
2018}
2019
2020//using ObjectWriteOperation/ObjectReadOperation with iohint
2021TEST(LibRadosAioEC, RoundTripWriteFullPP2)
2022{
2023 Rados cluster;
2024 std::string pool_name = get_temp_pool_name();
2025 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
2026 IoCtx ioctx;
2027 cluster.ioctx_create(pool_name.c_str(), ioctx);
2028
2029 boost::scoped_ptr<AioCompletion> my_completion1(cluster.aio_create_completion(0, 0, 0));
2030 ObjectWriteOperation op;
2031 char buf[128];
2032 memset(buf, 0xcc, sizeof(buf));
2033 bufferlist bl;
2034 bl.append(buf);
2035
2036 op.write_full(bl);
2037 op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE);
2038 ioctx.aio_operate("test_obj", my_completion1.get(), &op);
2039 {
2040 TestAlarm alarm;
2041 ASSERT_EQ(0, my_completion1->wait_for_complete());
2042 }
2043 EXPECT_EQ(0, my_completion1->get_return_value());
2044
2045 boost::scoped_ptr<AioCompletion> my_completion2(cluster.aio_create_completion(0, 0, 0));
2046 bl.clear();
2047 ObjectReadOperation op1;
2048 op1.read(0, sizeof(buf), &bl, NULL);
2049 op1.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_NOCACHE|LIBRADOS_OP_FLAG_FADVISE_RANDOM);
2050 ioctx.aio_operate("test_obj", my_completion2.get(), &op1, 0);
2051 {
2052 TestAlarm alarm;
2053 ASSERT_EQ(0, my_completion2->wait_for_complete());
2054 }
2055 EXPECT_EQ(0, my_completion2->get_return_value());
2056 ASSERT_EQ(0, memcmp(buf, bl.c_str(), sizeof(buf)));
2057
2058 ioctx.remove("test_obj");
2059 destroy_one_pool_pp(pool_name, cluster);
2060}
2061
2062TEST(LibRadosAioEC, SimpleStatPP) {
2063 AioTestDataECPP test_data;
2064 ASSERT_EQ("", test_data.init());
2065 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2066 nullptr, nullptr, nullptr);
2067 AioCompletion *my_completion_null = NULL;
2068 ASSERT_NE(my_completion, my_completion_null);
2069 char buf[128];
2070 memset(buf, 0xcc, sizeof(buf));
2071 bufferlist bl1;
2072 bl1.append(buf, sizeof(buf));
2073 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
2074 bl1, sizeof(buf), 0));
2075 {
2076 TestAlarm alarm;
2077 ASSERT_EQ(0, my_completion->wait_for_complete());
2078 }
2079 ASSERT_EQ(0, my_completion->get_return_value());
2080 uint64_t psize;
2081 time_t pmtime;
2082 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
2083 nullptr, nullptr, nullptr);
2084 ASSERT_NE(my_completion2, my_completion_null);
2085 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion2,
2086 &psize, &pmtime));
2087 {
2088 TestAlarm alarm;
2089 ASSERT_EQ(0, my_completion2->wait_for_complete());
2090 }
2091 ASSERT_EQ(0, my_completion2->get_return_value());
2092 ASSERT_EQ(sizeof(buf), psize);
2093 delete my_completion;
2094 delete my_completion2;
2095}
2096
2097TEST(LibRadosAioEC, SimpleStatPPNS) {
2098 AioTestDataECPP test_data;
2099 ASSERT_EQ("", test_data.init());
2100 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2101 nullptr, nullptr, nullptr);
2102 AioCompletion *my_completion_null = NULL;
2103 ASSERT_NE(my_completion, my_completion_null);
2104 char buf[128];
2105 memset(buf, 0xcc, sizeof(buf));
2106 bufferlist bl1;
2107 bl1.append(buf, sizeof(buf));
2108 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
2109 bl1, sizeof(buf), 0));
2110 {
2111 TestAlarm alarm;
2112 ASSERT_EQ(0, my_completion->wait_for_complete());
2113 }
2114 ASSERT_EQ(0, my_completion->get_return_value());
2115 uint64_t psize;
2116 time_t pmtime;
2117 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
2118 nullptr, nullptr, nullptr);
2119 ASSERT_NE(my_completion2, my_completion_null);
2120 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion2,
2121 &psize, &pmtime));
2122 {
2123 TestAlarm alarm;
2124 ASSERT_EQ(0, my_completion2->wait_for_complete());
2125 }
2126 ASSERT_EQ(0, my_completion2->get_return_value());
2127 ASSERT_EQ(sizeof(buf), psize);
2128 delete my_completion;
2129 delete my_completion2;
2130}
2131
2132TEST(LibRadosAioEC, StatRemovePP) {
2133 AioTestDataECPP test_data;
2134 ASSERT_EQ("", test_data.init());
2135 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2136 nullptr, nullptr, nullptr);
2137 AioCompletion *my_completion_null = NULL;
2138 ASSERT_NE(my_completion, my_completion_null);
2139 char buf[128];
2140 memset(buf, 0xcc, sizeof(buf));
2141 bufferlist bl1;
2142 bl1.append(buf, sizeof(buf));
2143 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
2144 bl1, sizeof(buf), 0));
2145 {
2146 TestAlarm alarm;
2147 ASSERT_EQ(0, my_completion->wait_for_complete());
2148 }
2149 ASSERT_EQ(0, my_completion->get_return_value());
2150 uint64_t psize;
2151 time_t pmtime;
2152 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
2153 nullptr, nullptr, nullptr);
2154 ASSERT_NE(my_completion2, my_completion_null);
2155 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion2,
2156 &psize, &pmtime));
2157 {
2158 TestAlarm alarm;
2159 ASSERT_EQ(0, my_completion2->wait_for_complete());
2160 }
2161 ASSERT_EQ(0, my_completion2->get_return_value());
2162 ASSERT_EQ(sizeof(buf), psize);
2163 uint64_t psize2;
2164 time_t pmtime2;
2165 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
2166 nullptr, nullptr, nullptr);
2167 ASSERT_NE(my_completion3, my_completion_null);
2168 ASSERT_EQ(0, test_data.m_ioctx.aio_remove("foo", my_completion3));
2169 {
2170 TestAlarm alarm;
2171 ASSERT_EQ(0, my_completion3->wait_for_complete());
2172 }
2173 ASSERT_EQ(0, my_completion3->get_return_value());
2174
2175 AioCompletion *my_completion4 = test_data.m_cluster.aio_create_completion(
2176 nullptr, nullptr, nullptr);
2177 ASSERT_NE(my_completion4, my_completion_null);
2178 ASSERT_EQ(0, test_data.m_ioctx.aio_stat("foo", my_completion4,
2179 &psize2, &pmtime2));
2180 {
2181 TestAlarm alarm;
2182 ASSERT_EQ(0, my_completion4->wait_for_complete());
2183 }
2184 ASSERT_EQ(-ENOENT, my_completion4->get_return_value());
2185 delete my_completion;
2186 delete my_completion2;
2187 delete my_completion3;
2188 delete my_completion4;
2189}
2190
2191TEST(LibRadosAioEC, ExecuteClassPP) {
2192 AioTestDataECPP test_data;
2193 ASSERT_EQ("", test_data.init());
2194 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2195 nullptr, nullptr, nullptr);
2196 AioCompletion *my_completion_null = NULL;
2197 ASSERT_NE(my_completion, my_completion_null);
2198 char buf[128];
2199 memset(buf, 0xcc, sizeof(buf));
2200 bufferlist bl1;
2201 bl1.append(buf, sizeof(buf));
2202 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
2203 bl1, sizeof(buf), 0));
2204 {
2205 TestAlarm alarm;
2206 ASSERT_EQ(0, my_completion->wait_for_complete());
2207 }
2208 ASSERT_EQ(0, my_completion->get_return_value());
2209 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
2210 nullptr, nullptr, nullptr);
2211 ASSERT_NE(my_completion2, my_completion_null);
2212 bufferlist in, out;
2213 ASSERT_EQ(0, test_data.m_ioctx.aio_exec("foo", my_completion2,
2214 "hello", "say_hello", in, &out));
2215 {
2216 TestAlarm alarm;
2217 ASSERT_EQ(0, my_completion2->wait_for_complete());
2218 }
2219 ASSERT_EQ(0, my_completion2->get_return_value());
2220 ASSERT_EQ(std::string("Hello, world!"), std::string(out.c_str(), out.length()));
2221 delete my_completion;
2222 delete my_completion2;
2223}
2224
2225TEST(LibRadosAioEC, OmapPP) {
2226 Rados cluster;
2227 std::string pool_name = get_temp_pool_name();
2228 ASSERT_EQ("", create_one_ec_pool_pp(pool_name, cluster));
2229 IoCtx ioctx;
2230 cluster.ioctx_create(pool_name.c_str(), ioctx);
2231
2232 string header_str = "baz";
2233 bufferptr bp(header_str.c_str(), header_str.size() + 1);
2234 bufferlist header_to_set;
2235 header_to_set.push_back(bp);
2236 map<string, bufferlist> to_set;
2237 {
2238 boost::scoped_ptr<AioCompletion> my_completion(cluster.aio_create_completion(0, 0, 0));
2239 ObjectWriteOperation op;
2240 to_set["foo"] = header_to_set;
2241 to_set["foo2"] = header_to_set;
2242 to_set["qfoo3"] = header_to_set;
2243 op.omap_set(to_set);
2244
2245 op.omap_set_header(header_to_set);
2246
2247 ioctx.aio_operate("test_obj", my_completion.get(), &op);
2248 {
2249 TestAlarm alarm;
2250 ASSERT_EQ(0, my_completion->wait_for_complete());
2251 }
2252 EXPECT_EQ(-EOPNOTSUPP, my_completion->get_return_value());
2253 }
2254 ioctx.remove("test_obj");
2255 destroy_one_pool_pp(pool_name, cluster);
2256}
2257
2258TEST(LibRadosAioEC, MultiWritePP) {
2259 AioTestDataECPP test_data;
2260 ASSERT_EQ("", test_data.init());
2261 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2262 nullptr, nullptr, nullptr);
2263 AioCompletion *my_completion_null = NULL;
2264 ASSERT_NE(my_completion, my_completion_null);
2265 char buf[128];
2266 memset(buf, 0xcc, sizeof(buf));
2267 bufferlist bl1;
2268 bl1.append(buf, sizeof(buf));
2269 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
2270 bl1, sizeof(buf), 0));
2271 {
2272 TestAlarm alarm;
2273 ASSERT_EQ(0, my_completion->wait_for_complete());
2274 }
2275 ASSERT_EQ(0, my_completion->get_return_value());
2276
2277 char buf2[64];
2278 memset(buf2, 0xdd, sizeof(buf2));
2279 bufferlist bl2;
2280 bl2.append(buf2, sizeof(buf2));
2281 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
2282 nullptr, nullptr, nullptr);
2283 ASSERT_NE(my_completion2, my_completion_null);
2284 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion2,
2285 bl2, sizeof(buf2), sizeof(buf)));
2286 {
2287 TestAlarm alarm;
2288 ASSERT_EQ(0, my_completion2->wait_for_complete());
2289 }
2290 ASSERT_EQ(-EOPNOTSUPP, my_completion2->get_return_value());
2291
2292 bufferlist bl3;
2293 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
2294 nullptr, nullptr, nullptr);
2295 ASSERT_NE(my_completion3, my_completion_null);
2296 ASSERT_EQ(0, test_data.m_ioctx.aio_read("foo", my_completion3,
2297 &bl3, (sizeof(buf) + sizeof(buf2) * 3), 0));
2298 {
2299 TestAlarm alarm;
2300 ASSERT_EQ(0, my_completion3->wait_for_complete());
2301 }
2302 ASSERT_EQ((int)sizeof(buf), my_completion3->get_return_value());
2303 ASSERT_EQ(sizeof(buf), bl3.length());
2304 ASSERT_EQ(0, memcmp(bl3.c_str(), buf, sizeof(buf)));
2305 delete my_completion;
2306 delete my_completion2;
2307 delete my_completion3;
2308}
2309
2310TEST(LibRadosAio, RacingRemovePP) {
2311 AioTestDataPP test_data;
2312 ASSERT_EQ("", test_data.init({{"objecter_retry_writes_after_first_reply", "true"}}));
2313 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2314 nullptr, nullptr, nullptr);
2315 ASSERT_NE(my_completion, nullptr);
2316 char buf[128];
2317 memset(buf, 0xcc, sizeof(buf));
2318 bufferlist bl;
2319 bl.append(buf, sizeof(buf));
2320 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
2321 nullptr, nullptr, nullptr);
2322 ASSERT_NE(my_completion2, nullptr);
2323 ASSERT_EQ(0, test_data.m_ioctx.aio_remove("foo", my_completion2));
2324 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
2325 bl, sizeof(buf), 0));
2326 {
2327 TestAlarm alarm;
2328 my_completion2->wait_for_complete();
2329 my_completion->wait_for_complete();
2330 }
2331 ASSERT_EQ(-ENOENT, my_completion2->get_return_value());
2332 ASSERT_EQ(0, my_completion->get_return_value());
2333 ASSERT_EQ(0, test_data.m_ioctx.stat("foo", nullptr, nullptr));
2334 delete my_completion;
2335 delete my_completion2;
2336}
2337
2338TEST(LibRadosAio, RoundTripCmpExtPP) {
2339 AioTestDataPP test_data;
2340 ASSERT_EQ("", test_data.init());
2341 AioCompletion *my_completion = test_data.m_cluster.aio_create_completion(
2342 nullptr, nullptr, nullptr);
2343 AioCompletion *my_completion_null = NULL;
2344 ASSERT_NE(my_completion, my_completion_null);
2345 char full[128];
2346 memset(full, 0xcc, sizeof(full));
2347 bufferlist bl1;
2348 bl1.append(full, sizeof(full));
2349 ASSERT_EQ(0, test_data.m_ioctx.aio_write("foo", my_completion,
2350 bl1, sizeof(full), 0));
2351 {
2352 TestAlarm alarm;
2353 ASSERT_EQ(0, my_completion->wait_for_complete());
2354 }
2355 ASSERT_EQ(0, my_completion->get_return_value());
2356
2357 /* compare with match */
2358 bufferlist cbl;
2359 cbl.append(full, sizeof(full));
2360 AioCompletion *my_completion2 = test_data.m_cluster.aio_create_completion(
2361 nullptr, nullptr, nullptr);
2362 ASSERT_EQ(0, test_data.m_ioctx.aio_cmpext("foo", my_completion2, 0, cbl));
2363
2364 {
2365 TestAlarm alarm;
2366 ASSERT_EQ(0, my_completion2->wait_for_complete());
2367 }
2368 ASSERT_EQ(0, my_completion2->get_return_value());
2369
2370 /* compare with mismatch */
2371 memset(full, 0xdd, sizeof(full));
2372 cbl.clear();
2373 cbl.append(full, sizeof(full));
2374 AioCompletion *my_completion3 = test_data.m_cluster.aio_create_completion(
2375 nullptr, nullptr, nullptr);
2376 ASSERT_EQ(0, test_data.m_ioctx.aio_cmpext("foo", my_completion3, 0, cbl));
2377
2378 {
2379 TestAlarm alarm;
2380 ASSERT_EQ(0, my_completion3->wait_for_complete());
2381 }
2382 ASSERT_EQ(-MAX_ERRNO, my_completion3->get_return_value());
2383
2384 delete my_completion;
2385 delete my_completion2;
2386 delete my_completion3;
2387}
2388
2389TEST(LibRadosAio, RoundTripCmpExtPP2)
2390{
2391 int ret;
2392 char buf[128];
2393 char miscmp_buf[128];
2394 bufferlist cbl;
2395 Rados cluster;
2396 std::string pool_name = get_temp_pool_name();
2397 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
2398 IoCtx ioctx;
2399 cluster.ioctx_create(pool_name.c_str(), ioctx);
2400
2401 boost::scoped_ptr<AioCompletion>
2402 wr_cmpl(cluster.aio_create_completion(0, 0, 0));
2403 ObjectWriteOperation wr_op;
2404 memset(buf, 0xcc, sizeof(buf));
2405 memset(miscmp_buf, 0xdd, sizeof(miscmp_buf));
2406 bufferlist bl;
2407 bl.append(buf, sizeof(buf));
2408
2409 wr_op.write_full(bl);
2410 wr_op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
2411 ioctx.aio_operate("test_obj", wr_cmpl.get(), &wr_op);
2412 {
2413 TestAlarm alarm;
2414 ASSERT_EQ(0, wr_cmpl->wait_for_complete());
2415 }
2416 EXPECT_EQ(0, wr_cmpl->get_return_value());
2417
2418 /* cmpext as write op. first match then mismatch */
2419 boost::scoped_ptr<AioCompletion>
2420 wr_cmpext_cmpl(cluster.aio_create_completion(0, 0, 0));
2421 cbl.append(buf, sizeof(buf));
2422 ret = 0;
2423
2424 wr_op.cmpext(0, cbl, &ret);
2425 wr_op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
2426 ioctx.aio_operate("test_obj", wr_cmpext_cmpl.get(), &wr_op);
2427 {
2428 TestAlarm alarm;
2429 ASSERT_EQ(0, wr_cmpext_cmpl->wait_for_complete());
2430 }
2431 EXPECT_EQ(0, wr_cmpext_cmpl->get_return_value());
2432 EXPECT_EQ(0, ret);
2433
2434 boost::scoped_ptr<AioCompletion>
2435 wr_cmpext_cmpl2(cluster.aio_create_completion(0, 0, 0));
2436 cbl.clear();
2437 cbl.append(miscmp_buf, sizeof(miscmp_buf));
2438 ret = 0;
2439
2440 wr_op.cmpext(0, cbl, &ret);
2441 wr_op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
2442 ioctx.aio_operate("test_obj", wr_cmpext_cmpl2.get(), &wr_op);
2443 {
2444 TestAlarm alarm;
2445 ASSERT_EQ(0, wr_cmpext_cmpl2->wait_for_complete());
2446 }
2447 EXPECT_EQ(-MAX_ERRNO, wr_cmpext_cmpl2->get_return_value());
2448 EXPECT_EQ(-MAX_ERRNO, ret);
2449
2450 /* cmpext as read op */
2451 boost::scoped_ptr<AioCompletion>
2452 rd_cmpext_cmpl(cluster.aio_create_completion(0, 0, 0));
2453 ObjectReadOperation rd_op;
2454 cbl.clear();
2455 cbl.append(buf, sizeof(buf));
2456 ret = 0;
2457 rd_op.cmpext(0, cbl, &ret);
2458 rd_op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
2459 ioctx.aio_operate("test_obj", rd_cmpext_cmpl.get(), &rd_op, 0);
2460 {
2461 TestAlarm alarm;
2462 ASSERT_EQ(0, rd_cmpext_cmpl->wait_for_complete());
2463 }
2464 EXPECT_EQ(0, rd_cmpext_cmpl->get_return_value());
2465 EXPECT_EQ(0, ret);
2466
2467 boost::scoped_ptr<AioCompletion>
2468 rd_cmpext_cmpl2(cluster.aio_create_completion(0, 0, 0));
2469 cbl.clear();
2470 cbl.append(miscmp_buf, sizeof(miscmp_buf));
2471 ret = 0;
2472
2473 rd_op.cmpext(0, cbl, &ret);
2474 rd_op.set_op_flags2(LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
2475 ioctx.aio_operate("test_obj", rd_cmpext_cmpl2.get(), &rd_op, 0);
2476 {
2477 TestAlarm alarm;
2478 ASSERT_EQ(0, rd_cmpext_cmpl2->wait_for_complete());
2479 }
2480 EXPECT_EQ(-MAX_ERRNO, rd_cmpext_cmpl2->get_return_value());
2481 EXPECT_EQ(-MAX_ERRNO, ret);
2482
2483 ioctx.remove("test_obj");
2484 destroy_one_pool_pp(pool_name, cluster);
2485}