]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librados/aio.cc
import ceph 14.2.5
[ceph.git] / ceph / src / test / librados / aio.cc
1 #include <errno.h>
2 #include <fcntl.h>
3 #include <string>
4 #include <sstream>
5 #include <utility>
6 #include <boost/scoped_ptr.hpp>
7
8 #include "include/err.h"
9 #include "include/rados/librados.h"
10 #include "include/types.h"
11 #include "include/stringify.h"
12 #include "include/scope_guard.h"
13
14 #include "common/errno.h"
15
16 #include "gtest/gtest.h"
17
18 #include "test.h"
19
20 using std::ostringstream;
21
22 class AioTestData
23 {
24 public:
25 AioTestData()
26 : m_cluster(NULL),
27 m_ioctx(NULL),
28 m_init(false)
29 {
30 }
31
32 ~AioTestData()
33 {
34 if (m_init) {
35 rados_ioctx_destroy(m_ioctx);
36 destroy_one_pool(m_pool_name, &m_cluster);
37 }
38 }
39
40 std::string init()
41 {
42 int ret;
43 m_pool_name = get_temp_pool_name();
44 std::string err = create_one_pool(m_pool_name, &m_cluster);
45 if (!err.empty()) {
46 ostringstream oss;
47 oss << "create_one_pool(" << m_pool_name << ") failed: error " << err;
48 return oss.str();
49 }
50 ret = rados_ioctx_create(m_cluster, m_pool_name.c_str(), &m_ioctx);
51 if (ret) {
52 destroy_one_pool(m_pool_name, &m_cluster);
53 ostringstream oss;
54 oss << "rados_ioctx_create failed: error " << ret;
55 return oss.str();
56 }
57 m_init = true;
58 return "";
59 }
60
61 rados_t m_cluster;
62 rados_ioctx_t m_ioctx;
63 std::string m_pool_name;
64 bool m_init;
65 };
66
67 TEST(LibRadosAio, TooBig) {
68 AioTestData test_data;
69 rados_completion_t my_completion;
70 ASSERT_EQ("", test_data.init());
71 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
72 nullptr, nullptr, &my_completion));
73 char buf[128];
74 memset(buf, 0xcc, sizeof(buf));
75 ASSERT_EQ(-E2BIG, rados_aio_write(test_data.m_ioctx, "foo",
76 my_completion, buf, UINT_MAX, 0));
77 ASSERT_EQ(-E2BIG, rados_aio_write_full(test_data.m_ioctx, "foo",
78 my_completion, buf, UINT_MAX));
79 ASSERT_EQ(-E2BIG, rados_aio_append(test_data.m_ioctx, "foo",
80 my_completion, buf, UINT_MAX));
81 rados_aio_release(my_completion);
82 }
83
84 TEST(LibRadosAio, SimpleWrite) {
85 AioTestData test_data;
86 rados_completion_t my_completion;
87 ASSERT_EQ("", test_data.init());
88 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
89 nullptr, nullptr, &my_completion));
90 auto sg = make_scope_guard([&] { rados_aio_release(my_completion); });
91 char buf[128];
92 memset(buf, 0xcc, sizeof(buf));
93 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
94 my_completion, buf, sizeof(buf), 0));
95 {
96 TestAlarm alarm;
97 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
98 }
99 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
100
101 rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
102 rados_completion_t my_completion2;
103 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
104 nullptr, nullptr, &my_completion2));
105 auto sg2 = make_scope_guard([&] { rados_aio_release(my_completion2); });
106 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
107 my_completion2, buf, sizeof(buf), 0));
108 {
109 TestAlarm alarm;
110 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
111 }
112 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
113 }
114
115 TEST(LibRadosAio, WaitForSafe) {
116 AioTestData test_data;
117 rados_completion_t my_completion;
118 ASSERT_EQ("", test_data.init());
119 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
120 nullptr, nullptr, &my_completion));
121 char buf[128];
122 memset(buf, 0xcc, sizeof(buf));
123 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
124 my_completion, buf, sizeof(buf), 0));
125 TestAlarm alarm;
126 ASSERT_EQ(0, rados_aio_wait_for_safe(my_completion));
127 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
128 rados_aio_release(my_completion);
129 }
130
131 TEST(LibRadosAio, RoundTrip) {
132 AioTestData test_data;
133 rados_completion_t my_completion;
134 ASSERT_EQ("", test_data.init());
135 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
136 nullptr, nullptr, &my_completion));
137 char buf[128];
138 memset(buf, 0xcc, sizeof(buf));
139 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
140 my_completion, buf, sizeof(buf), 0));
141 {
142 TestAlarm alarm;
143 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
144 }
145 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
146 char buf2[256];
147 memset(buf2, 0, sizeof(buf2));
148 rados_completion_t my_completion2;
149 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
150 nullptr, nullptr, &my_completion2));
151 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
152 my_completion2, buf2, sizeof(buf2), 0));
153 {
154 TestAlarm alarm;
155 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
156 }
157 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
158 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
159 rados_aio_release(my_completion);
160 rados_aio_release(my_completion2);
161 }
162
163 TEST(LibRadosAio, RoundTrip2) {
164 AioTestData test_data;
165 rados_completion_t my_completion;
166 ASSERT_EQ("", test_data.init());
167 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
168 nullptr, nullptr, &my_completion));
169 char buf[128];
170 memset(buf, 0xcc, sizeof(buf));
171 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
172 my_completion, buf, sizeof(buf), 0));
173 {
174 TestAlarm alarm;
175 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
176 }
177 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
178 char buf2[128];
179 memset(buf2, 0, sizeof(buf2));
180 rados_completion_t my_completion2;
181 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
182 nullptr, nullptr, &my_completion2));
183 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
184 my_completion2, buf2, sizeof(buf2), 0));
185 {
186 TestAlarm alarm;
187 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
188 }
189 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
190 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
191 rados_aio_release(my_completion);
192 rados_aio_release(my_completion2);
193 }
194
195 TEST(LibRadosAio, RoundTrip3) {
196 AioTestData test_data;
197 rados_completion_t my_completion;
198 ASSERT_EQ("", test_data.init());
199 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
200 nullptr, nullptr, &my_completion));
201 char buf[128];
202 memset(buf, 0xcc, sizeof(buf));
203
204 rados_write_op_t op1 = rados_create_write_op();
205 rados_write_op_write(op1, buf, sizeof(buf), 0);
206 rados_write_op_set_alloc_hint2(op1, 0, 0, LIBRADOS_OP_FLAG_FADVISE_DONTNEED);
207 ASSERT_EQ(0, rados_aio_write_op_operate(op1, test_data.m_ioctx, my_completion,
208 "foo", NULL, 0));
209 rados_release_write_op(op1);
210
211 {
212 TestAlarm alarm;
213 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
214 }
215
216 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
217 rados_aio_release(my_completion);
218
219 char buf2[128];
220 memset(buf2, 0, sizeof(buf2));
221 rados_completion_t my_completion2;
222 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
223 nullptr, nullptr, &my_completion2));
224
225 rados_read_op_t op2 = rados_create_read_op();
226 rados_read_op_read(op2, 0, sizeof(buf2), buf2, NULL, NULL);
227 rados_read_op_set_flags(op2, LIBRADOS_OP_FLAG_FADVISE_NOCACHE |
228 LIBRADOS_OP_FLAG_FADVISE_RANDOM);
229 ceph_le32 init_value = init_le32(-1);
230 ceph_le32 checksum[2];
231 rados_read_op_checksum(op2, LIBRADOS_CHECKSUM_TYPE_CRC32C,
232 reinterpret_cast<char *>(&init_value),
233 sizeof(init_value), 0, 0, 0,
234 reinterpret_cast<char *>(&checksum),
235 sizeof(checksum), NULL);
236 ASSERT_EQ(0, rados_aio_read_op_operate(op2, test_data.m_ioctx, my_completion2,
237 "foo", 0));
238 rados_release_read_op(op2);
239
240 {
241 TestAlarm alarm;
242 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
243 }
244 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
245 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
246 rados_aio_release(my_completion2);
247
248 bufferlist bl;
249 bl.append(buf, sizeof(buf));
250 ASSERT_EQ(1U, checksum[0]);
251 ASSERT_EQ(bl.crc32c(-1), checksum[1]);
252 }
253
254 TEST(LibRadosAio, RoundTripAppend) {
255 AioTestData test_data;
256 rados_completion_t my_completion, my_completion2, my_completion3;
257 ASSERT_EQ("", test_data.init());
258 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
259 nullptr, nullptr, &my_completion));
260 char buf[128];
261 memset(buf, 0xcc, sizeof(buf));
262 ASSERT_EQ(0, rados_aio_append(test_data.m_ioctx, "foo",
263 my_completion, buf, sizeof(buf)));
264 {
265 TestAlarm alarm;
266 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
267 }
268 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
269 char buf2[128];
270 memset(buf2, 0xdd, sizeof(buf2));
271 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
272 nullptr, nullptr, &my_completion2));
273 ASSERT_EQ(0, rados_aio_append(test_data.m_ioctx, "foo",
274 my_completion2, buf2, sizeof(buf2)));
275 {
276 TestAlarm alarm;
277 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
278 }
279 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
280 char buf3[sizeof(buf) + sizeof(buf2)];
281 memset(buf3, 0, sizeof(buf3));
282 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
283 nullptr, nullptr, &my_completion3));
284 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
285 my_completion3, buf3, sizeof(buf3), 0));
286 {
287 TestAlarm alarm;
288 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
289 }
290 ASSERT_EQ((int)sizeof(buf3), rados_aio_get_return_value(my_completion3));
291 ASSERT_EQ(0, memcmp(buf3, buf, sizeof(buf)));
292 ASSERT_EQ(0, memcmp(buf3 + sizeof(buf), buf2, sizeof(buf2)));
293 rados_aio_release(my_completion);
294 rados_aio_release(my_completion2);
295 rados_aio_release(my_completion3);
296 }
297
298 TEST(LibRadosAio, RemoveTest) {
299 char buf[128];
300 char buf2[sizeof(buf)];
301 rados_completion_t my_completion;
302 AioTestData test_data;
303 ASSERT_EQ("", test_data.init());
304 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
305 nullptr, nullptr, &my_completion));
306 memset(buf, 0xaa, sizeof(buf));
307 ASSERT_EQ(0, rados_append(test_data.m_ioctx, "foo", buf, sizeof(buf)));
308 ASSERT_EQ(0, rados_aio_remove(test_data.m_ioctx, "foo", my_completion));
309 {
310 TestAlarm alarm;
311 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
312 }
313 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
314 memset(buf2, 0, sizeof(buf2));
315 ASSERT_EQ(-ENOENT, rados_read(test_data.m_ioctx, "foo", buf2, sizeof(buf2), 0));
316 rados_aio_release(my_completion);
317 }
318
319 TEST(LibRadosAio, XattrsRoundTrip) {
320 char buf[128];
321 char attr1[] = "attr1";
322 char attr1_buf[] = "foo bar baz";
323 // append
324 AioTestData test_data;
325 ASSERT_EQ("", test_data.init());
326 memset(buf, 0xaa, sizeof(buf));
327 ASSERT_EQ(0, rados_append(test_data.m_ioctx, "foo", buf, sizeof(buf)));
328 // async getxattr
329 rados_completion_t my_completion;
330 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
331 nullptr, nullptr, &my_completion));
332 ASSERT_EQ(0, rados_aio_getxattr(test_data.m_ioctx, "foo", my_completion, attr1, buf, sizeof(buf)));
333 {
334 TestAlarm alarm;
335 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
336 }
337 ASSERT_EQ(-ENODATA, rados_aio_get_return_value(my_completion));
338 rados_aio_release(my_completion);
339 // async setxattr
340 rados_completion_t my_completion2;
341 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
342 nullptr, nullptr, &my_completion2));
343 ASSERT_EQ(0, rados_aio_setxattr(test_data.m_ioctx, "foo", my_completion2, attr1, attr1_buf, sizeof(attr1_buf)));
344 {
345 TestAlarm alarm;
346 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
347 }
348 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
349 rados_aio_release(my_completion2);
350 // async getxattr
351 rados_completion_t my_completion3;
352 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
353 nullptr, nullptr, &my_completion3));
354 ASSERT_EQ(0, rados_aio_getxattr(test_data.m_ioctx, "foo", my_completion3, attr1, buf, sizeof(buf)));
355 {
356 TestAlarm alarm;
357 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
358 }
359 ASSERT_EQ((int)sizeof(attr1_buf), rados_aio_get_return_value(my_completion3));
360 rados_aio_release(my_completion3);
361 // check content of attribute
362 ASSERT_EQ(0, memcmp(attr1_buf, buf, sizeof(attr1_buf)));
363 }
364
365 TEST(LibRadosAio, RmXattr) {
366 char buf[128];
367 char attr1[] = "attr1";
368 char attr1_buf[] = "foo bar baz";
369 // append
370 memset(buf, 0xaa, sizeof(buf));
371 AioTestData test_data;
372 ASSERT_EQ("", test_data.init());
373 ASSERT_EQ(0, rados_append(test_data.m_ioctx, "foo", buf, sizeof(buf)));
374 // async setxattr
375 rados_completion_t my_completion;
376 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
377 nullptr, nullptr, &my_completion));
378 ASSERT_EQ(0, rados_aio_setxattr(test_data.m_ioctx, "foo", my_completion, attr1, attr1_buf, sizeof(attr1_buf)));
379 {
380 TestAlarm alarm;
381 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
382 }
383 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
384 rados_aio_release(my_completion);
385 // async rmxattr
386 rados_completion_t my_completion2;
387 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
388 nullptr, nullptr, &my_completion2));
389 ASSERT_EQ(0, rados_aio_rmxattr(test_data.m_ioctx, "foo", my_completion2, attr1));
390 {
391 TestAlarm alarm;
392 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
393 }
394 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
395 rados_aio_release(my_completion2);
396 // async getxattr after deletion
397 rados_completion_t my_completion3;
398 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
399 nullptr, nullptr, &my_completion3));
400 ASSERT_EQ(0, rados_aio_getxattr(test_data.m_ioctx, "foo", my_completion3, attr1, buf, sizeof(buf)));
401 {
402 TestAlarm alarm;
403 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
404 }
405 ASSERT_EQ(-ENODATA, rados_aio_get_return_value(my_completion3));
406 rados_aio_release(my_completion3);
407 // Test rmxattr on a removed object
408 char buf2[128];
409 char attr2[] = "attr2";
410 char attr2_buf[] = "foo bar baz";
411 memset(buf2, 0xbb, sizeof(buf2));
412 ASSERT_EQ(0, rados_write(test_data.m_ioctx, "foo_rmxattr", buf2, sizeof(buf2), 0));
413 // asynx setxattr
414 rados_completion_t my_completion4;
415 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
416 nullptr, nullptr, &my_completion4));
417 ASSERT_EQ(0, rados_aio_setxattr(test_data.m_ioctx, "foo_rmxattr", my_completion4, attr2, attr2_buf, sizeof(attr2_buf)));
418 {
419 TestAlarm alarm;
420 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4));
421 }
422 ASSERT_EQ(0, rados_aio_get_return_value(my_completion4));
423 rados_aio_release(my_completion4);
424 // remove object
425 ASSERT_EQ(0, rados_remove(test_data.m_ioctx, "foo_rmxattr"));
426 // async rmxattr on non existing object
427 rados_completion_t my_completion5;
428 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
429 nullptr, nullptr, &my_completion5));
430 ASSERT_EQ(0, rados_aio_rmxattr(test_data.m_ioctx, "foo_rmxattr", my_completion5, attr2));
431 {
432 TestAlarm alarm;
433 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion5));
434 }
435 ASSERT_EQ(-ENOENT, rados_aio_get_return_value(my_completion5));
436 rados_aio_release(my_completion5);
437 }
438
439 TEST(LibRadosAio, XattrIter) {
440 AioTestData test_data;
441 ASSERT_EQ("", test_data.init());
442 // Create an object with 2 attributes
443 char buf[128];
444 char attr1[] = "attr1";
445 char attr1_buf[] = "foo bar baz";
446 char attr2[] = "attr2";
447 char attr2_buf[256];
448 for (size_t j = 0; j < sizeof(attr2_buf); ++j) {
449 attr2_buf[j] = j % 0xff;
450 }
451 memset(buf, 0xaa, sizeof(buf));
452 ASSERT_EQ(0, rados_append(test_data.m_ioctx, "foo", buf, sizeof(buf)));
453 ASSERT_EQ(0, rados_setxattr(test_data.m_ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf)));
454 ASSERT_EQ(0, rados_setxattr(test_data.m_ioctx, "foo", attr2, attr2_buf, sizeof(attr2_buf)));
455 // call async version of getxattrs and wait for completion
456 rados_completion_t my_completion;
457 ASSERT_EQ(0, rados_aio_create_completion((void*)&test_data,
458 nullptr, nullptr, &my_completion));
459 rados_xattrs_iter_t iter;
460 ASSERT_EQ(0, rados_aio_getxattrs(test_data.m_ioctx, "foo", my_completion, &iter));
461 {
462 TestAlarm alarm;
463 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
464 }
465 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
466 // loop over attributes
467 int num_seen = 0;
468 while (true) {
469 const char *name;
470 const char *val;
471 size_t len;
472 ASSERT_EQ(0, rados_getxattrs_next(iter, &name, &val, &len));
473 if (name == NULL) {
474 break;
475 }
476 ASSERT_LT(num_seen, 2);
477 if ((strcmp(name, attr1) == 0) && (val != NULL) && (memcmp(val, attr1_buf, len) == 0)) {
478 num_seen++;
479 continue;
480 }
481 else if ((strcmp(name, attr2) == 0) && (val != NULL) && (memcmp(val, attr2_buf, len) == 0)) {
482 num_seen++;
483 continue;
484 }
485 else {
486 ASSERT_EQ(0, 1);
487 }
488 }
489 rados_getxattrs_end(iter);
490 }
491
492 TEST(LibRadosAio, IsComplete) {
493 AioTestData test_data;
494 rados_completion_t my_completion;
495 ASSERT_EQ("", test_data.init());
496 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
497 nullptr, nullptr, &my_completion));
498 char buf[128];
499 memset(buf, 0xcc, sizeof(buf));
500 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
501 my_completion, buf, sizeof(buf), 0));
502 {
503 TestAlarm alarm;
504 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
505 }
506 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
507 char buf2[128];
508 memset(buf2, 0, sizeof(buf2));
509 rados_completion_t my_completion2;
510 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
511 nullptr, nullptr, &my_completion2));
512 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
513 my_completion2, buf2, sizeof(buf2), 0));
514 {
515 TestAlarm alarm;
516
517 // Busy-wait until the AIO completes.
518 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
519 while (true) {
520 int is_complete = rados_aio_is_complete(my_completion2);
521 if (is_complete)
522 break;
523 }
524 }
525 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
526 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
527 rados_aio_release(my_completion);
528 rados_aio_release(my_completion2);
529 }
530
531 TEST(LibRadosAio, IsSafe) {
532 AioTestData test_data;
533 rados_completion_t my_completion;
534 ASSERT_EQ("", test_data.init());
535 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
536 nullptr, nullptr, &my_completion));
537 char buf[128];
538 memset(buf, 0xcc, sizeof(buf));
539 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
540 my_completion, buf, sizeof(buf), 0));
541 {
542 TestAlarm alarm;
543
544 // Busy-wait until the AIO completes.
545 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
546 while (true) {
547 int is_safe = rados_aio_is_safe(my_completion);
548 if (is_safe)
549 break;
550 }
551 }
552 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
553 char buf2[128];
554 memset(buf2, 0, sizeof(buf2));
555 rados_completion_t my_completion2;
556 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
557 nullptr, nullptr, &my_completion2));
558 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
559 my_completion2, buf2, sizeof(buf2), 0));
560 {
561 TestAlarm alarm;
562 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
563 }
564 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
565 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
566 rados_aio_release(my_completion);
567 rados_aio_release(my_completion2);
568 }
569
570 TEST(LibRadosAio, ReturnValue) {
571 AioTestData test_data;
572 rados_completion_t my_completion;
573 ASSERT_EQ("", test_data.init());
574 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
575 nullptr, nullptr, &my_completion));
576 char buf[128];
577 memset(buf, 0, sizeof(buf));
578 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "nonexistent",
579 my_completion, buf, sizeof(buf), 0));
580 {
581 TestAlarm alarm;
582 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
583 }
584 ASSERT_EQ(-ENOENT, rados_aio_get_return_value(my_completion));
585 rados_aio_release(my_completion);
586 }
587
588 TEST(LibRadosAio, Flush) {
589 AioTestData test_data;
590 rados_completion_t my_completion;
591 ASSERT_EQ("", test_data.init());
592 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
593 nullptr, nullptr, &my_completion));
594 char buf[128];
595 memset(buf, 0xee, sizeof(buf));
596 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
597 my_completion, buf, sizeof(buf), 0));
598 ASSERT_EQ(0, rados_aio_flush(test_data.m_ioctx));
599 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
600 char buf2[128];
601 memset(buf2, 0, sizeof(buf2));
602 rados_completion_t my_completion2;
603 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
604 nullptr, nullptr, &my_completion2));
605 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
606 my_completion2, buf2, sizeof(buf2), 0));
607 {
608 TestAlarm alarm;
609 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
610 }
611 ASSERT_EQ((int)sizeof(buf2), rados_aio_get_return_value(my_completion2));
612 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
613 rados_aio_release(my_completion);
614 rados_aio_release(my_completion2);
615 }
616
617 TEST(LibRadosAio, FlushAsync) {
618 AioTestData test_data;
619 rados_completion_t my_completion;
620 ASSERT_EQ("", test_data.init());
621 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
622 nullptr, nullptr, &my_completion));
623 rados_completion_t flush_completion;
624 ASSERT_EQ(0, rados_aio_create_completion(NULL, NULL, NULL, &flush_completion));
625 char buf[128];
626 memset(buf, 0xee, sizeof(buf));
627 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
628 my_completion, buf, sizeof(buf), 0));
629 ASSERT_EQ(0, rados_aio_flush_async(test_data.m_ioctx, flush_completion));
630 {
631 TestAlarm alarm;
632 ASSERT_EQ(0, rados_aio_wait_for_complete(flush_completion));
633 ASSERT_EQ(0, rados_aio_wait_for_safe(flush_completion));
634 }
635 ASSERT_EQ(1, rados_aio_is_complete(my_completion));
636 ASSERT_EQ(1, rados_aio_is_safe(my_completion));
637 ASSERT_EQ(1, rados_aio_is_complete(flush_completion));
638 ASSERT_EQ(1, rados_aio_is_safe(flush_completion));
639 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
640 char buf2[128];
641 memset(buf2, 0, sizeof(buf2));
642 rados_completion_t my_completion2;
643 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
644 nullptr, nullptr, &my_completion2));
645 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
646 my_completion2, buf2, sizeof(buf2), 0));
647 {
648 TestAlarm alarm;
649 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
650 }
651 ASSERT_EQ((int)sizeof(buf2), rados_aio_get_return_value(my_completion2));
652 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
653 rados_aio_release(my_completion);
654 rados_aio_release(my_completion2);
655 rados_aio_release(flush_completion);
656 }
657
658 TEST(LibRadosAio, RoundTripWriteFull) {
659 AioTestData test_data;
660 rados_completion_t my_completion, my_completion2, my_completion3;
661 ASSERT_EQ("", test_data.init());
662 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
663 nullptr, nullptr, &my_completion));
664 char buf[128];
665 memset(buf, 0xcc, sizeof(buf));
666 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
667 my_completion, buf, sizeof(buf), 0));
668 {
669 TestAlarm alarm;
670 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
671 }
672 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
673 char buf2[64];
674 memset(buf2, 0xdd, sizeof(buf2));
675 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
676 nullptr, nullptr, &my_completion2));
677 ASSERT_EQ(0, rados_aio_write_full(test_data.m_ioctx, "foo",
678 my_completion2, buf2, sizeof(buf2)));
679 {
680 TestAlarm alarm;
681 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
682 }
683 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
684 char buf3[sizeof(buf) + sizeof(buf2)];
685 memset(buf3, 0, sizeof(buf3));
686 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
687 nullptr, nullptr, &my_completion3));
688 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
689 my_completion3, buf3, sizeof(buf3), 0));
690 {
691 TestAlarm alarm;
692 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
693 }
694 ASSERT_EQ((int)sizeof(buf2), rados_aio_get_return_value(my_completion3));
695 ASSERT_EQ(0, memcmp(buf3, buf2, sizeof(buf2)));
696 rados_aio_release(my_completion);
697 rados_aio_release(my_completion2);
698 rados_aio_release(my_completion3);
699 }
700
701 TEST(LibRadosAio, RoundTripWriteSame) {
702 AioTestData test_data;
703 rados_completion_t my_completion, my_completion2, my_completion3;
704 ASSERT_EQ("", test_data.init());
705 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
706 nullptr, nullptr, &my_completion));
707 char full[128];
708 memset(full, 0xcc, sizeof(full));
709 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
710 my_completion, full, sizeof(full), 0));
711 {
712 TestAlarm alarm;
713 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
714 }
715 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
716 /* write the same buf four times */
717 char buf[32];
718 size_t ws_write_len = sizeof(full);
719 memset(buf, 0xdd, sizeof(buf));
720 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
721 nullptr, nullptr, &my_completion2));
722 ASSERT_EQ(0, rados_aio_writesame(test_data.m_ioctx, "foo",
723 my_completion2, buf, sizeof(buf),
724 ws_write_len, 0));
725 {
726 TestAlarm alarm;
727 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
728 }
729 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
730 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
731 nullptr, nullptr, &my_completion3));
732 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
733 my_completion3, full, sizeof(full), 0));
734 {
735 TestAlarm alarm;
736 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
737 }
738 ASSERT_EQ((int)sizeof(full), rados_aio_get_return_value(my_completion3));
739 for (char *cmp = full; cmp < full + sizeof(full); cmp += sizeof(buf)) {
740 ASSERT_EQ(0, memcmp(cmp, buf, sizeof(buf)));
741 }
742 rados_aio_release(my_completion);
743 rados_aio_release(my_completion2);
744 rados_aio_release(my_completion3);
745 }
746
747 TEST(LibRadosAio, SimpleStat) {
748 AioTestData test_data;
749 rados_completion_t my_completion;
750 ASSERT_EQ("", test_data.init());
751 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
752 nullptr, nullptr, &my_completion));
753 char buf[128];
754 memset(buf, 0xcc, sizeof(buf));
755 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
756 my_completion, buf, sizeof(buf), 0));
757 {
758 TestAlarm alarm;
759 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
760 }
761 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
762 uint64_t psize;
763 time_t pmtime;
764 rados_completion_t my_completion2;
765 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
766 nullptr, nullptr, &my_completion2));
767 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
768 my_completion2, &psize, &pmtime));
769 {
770 TestAlarm alarm;
771 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
772 }
773 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
774 ASSERT_EQ(sizeof(buf), psize);
775 rados_aio_release(my_completion);
776 rados_aio_release(my_completion2);
777 }
778
779 TEST(LibRadosAio, SimpleStatNS) {
780 AioTestData test_data;
781 rados_completion_t my_completion;
782 ASSERT_EQ("", test_data.init());
783 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
784 nullptr, nullptr, &my_completion));
785 char buf[128];
786 memset(buf, 0xcc, sizeof(buf));
787 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
788 my_completion, buf, sizeof(buf), 0));
789 {
790 TestAlarm alarm;
791 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
792 }
793 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
794 rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
795 char buf2[64];
796 memset(buf2, 0xbb, sizeof(buf2));
797 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
798 nullptr, nullptr, &my_completion));
799 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
800 my_completion, buf2, sizeof(buf2), 0));
801 {
802 TestAlarm alarm;
803 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
804 }
805 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
806 uint64_t psize;
807 time_t pmtime;
808 rados_completion_t my_completion2;
809 rados_ioctx_set_namespace(test_data.m_ioctx, "");
810 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
811 nullptr, nullptr, &my_completion2));
812 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
813 my_completion2, &psize, &pmtime));
814 {
815 TestAlarm alarm;
816 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
817 }
818 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
819 ASSERT_EQ(sizeof(buf), psize);
820
821 rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
822 rados_completion_t my_completion3;
823 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
824 nullptr, nullptr, &my_completion3));
825 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
826 my_completion3, &psize, &pmtime));
827 {
828 TestAlarm alarm;
829 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
830 }
831 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3));
832 ASSERT_EQ(sizeof(buf2), psize);
833
834 rados_aio_release(my_completion);
835 rados_aio_release(my_completion2);
836 rados_aio_release(my_completion3);
837 }
838
839 TEST(LibRadosAio, StatRemove) {
840 AioTestData test_data;
841 rados_completion_t my_completion;
842 ASSERT_EQ("", test_data.init());
843 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
844 nullptr, nullptr, &my_completion));
845 char buf[128];
846 memset(buf, 0xcc, sizeof(buf));
847 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
848 my_completion, buf, sizeof(buf), 0));
849 {
850 TestAlarm alarm;
851 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
852 }
853 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
854 uint64_t psize;
855 time_t pmtime;
856 rados_completion_t my_completion2;
857 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
858 nullptr, nullptr, &my_completion2));
859 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
860 my_completion2, &psize, &pmtime));
861 {
862 TestAlarm alarm;
863 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
864 }
865 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
866 ASSERT_EQ(sizeof(buf), psize);
867 rados_completion_t my_completion3;
868 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
869 nullptr, nullptr, &my_completion3));
870 ASSERT_EQ(0, rados_aio_remove(test_data.m_ioctx, "foo", my_completion3));
871 {
872 TestAlarm alarm;
873 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
874 }
875 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3));
876 uint64_t psize2;
877 time_t pmtime2;
878 rados_completion_t my_completion4;
879 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
880 nullptr, nullptr, &my_completion4));
881 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
882 my_completion4, &psize2, &pmtime2));
883 {
884 TestAlarm alarm;
885 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4));
886 }
887 ASSERT_EQ(-ENOENT, rados_aio_get_return_value(my_completion4));
888 rados_aio_release(my_completion);
889 rados_aio_release(my_completion2);
890 rados_aio_release(my_completion3);
891 rados_aio_release(my_completion4);
892 }
893
894 TEST(LibRadosAio, ExecuteClass) {
895 AioTestData test_data;
896 rados_completion_t my_completion;
897 ASSERT_EQ("", test_data.init());
898 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
899 nullptr, nullptr, &my_completion));
900 char buf[128];
901 memset(buf, 0xcc, sizeof(buf));
902 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
903 my_completion, buf, sizeof(buf), 0));
904 {
905 TestAlarm alarm;
906 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
907 }
908 rados_completion_t my_completion2;
909 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
910 nullptr, nullptr, &my_completion2));
911 char out[128];
912 ASSERT_EQ(0, rados_aio_exec(test_data.m_ioctx, "foo", my_completion2,
913 "hello", "say_hello", NULL, 0, out, sizeof(out)));
914 {
915 TestAlarm alarm;
916 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
917 }
918 ASSERT_EQ(13, rados_aio_get_return_value(my_completion2));
919 ASSERT_EQ(0, strncmp("Hello, world!", out, 13));
920 rados_aio_release(my_completion);
921 rados_aio_release(my_completion2);
922 }
923
924 using std::string;
925 using std::map;
926 using std::set;
927
928 TEST(LibRadosAio, MultiWrite) {
929 AioTestData test_data;
930 rados_completion_t my_completion, my_completion2, my_completion3;
931 ASSERT_EQ("", test_data.init());
932 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
933 nullptr, nullptr, &my_completion));
934 char buf[128];
935 memset(buf, 0xcc, sizeof(buf));
936 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
937 my_completion, buf, sizeof(buf), 0));
938 {
939 TestAlarm alarm;
940 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
941 }
942 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
943
944 char buf2[64];
945 memset(buf2, 0xdd, sizeof(buf2));
946 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
947 nullptr, nullptr, &my_completion2));
948 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
949 my_completion2, buf2, sizeof(buf2), sizeof(buf)));
950 {
951 TestAlarm alarm;
952 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
953 }
954 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
955
956 char buf3[(sizeof(buf) + sizeof(buf2)) * 3];
957 memset(buf3, 0, sizeof(buf3));
958 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
959 nullptr, nullptr, &my_completion3));
960 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
961 my_completion3, buf3, sizeof(buf3), 0));
962 {
963 TestAlarm alarm;
964 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
965 }
966 ASSERT_EQ((int)(sizeof(buf) + sizeof(buf2)), rados_aio_get_return_value(my_completion3));
967 ASSERT_EQ(0, memcmp(buf3, buf, sizeof(buf)));
968 ASSERT_EQ(0, memcmp(buf3 + sizeof(buf), buf2, sizeof(buf2)));
969 rados_aio_release(my_completion);
970 rados_aio_release(my_completion2);
971 rados_aio_release(my_completion3);
972 }
973
974 TEST(LibRadosAio, AioUnlock) {
975 AioTestData test_data;
976 ASSERT_EQ("", test_data.init());
977 ASSERT_EQ(0, rados_lock_exclusive(test_data.m_ioctx, "foo", "TestLock", "Cookie", "", NULL, 0));
978 rados_completion_t my_completion;
979 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
980 nullptr, nullptr, &my_completion));
981 ASSERT_EQ(0, rados_aio_unlock(test_data.m_ioctx, "foo", "TestLock", "Cookie", my_completion));
982 {
983 TestAlarm alarm;
984 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
985 }
986 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
987 ASSERT_EQ(0, rados_lock_exclusive(test_data.m_ioctx, "foo", "TestLock", "Cookie", "", NULL, 0));
988 }
989
990 // EC test cases
991 class AioTestDataEC
992 {
993 public:
994 AioTestDataEC()
995 : m_cluster(NULL),
996 m_ioctx(NULL),
997 m_init(false)
998 {
999 }
1000
1001 ~AioTestDataEC()
1002 {
1003 if (m_init) {
1004 rados_ioctx_destroy(m_ioctx);
1005 destroy_one_ec_pool(m_pool_name, &m_cluster);
1006 }
1007 }
1008
1009 std::string init()
1010 {
1011 int ret;
1012 m_pool_name = get_temp_pool_name();
1013 std::string err = create_one_ec_pool(m_pool_name, &m_cluster);
1014 if (!err.empty()) {
1015 ostringstream oss;
1016 oss << "create_one_ec_pool(" << m_pool_name << ") failed: error " << err;
1017 return oss.str();
1018 }
1019 ret = rados_ioctx_create(m_cluster, m_pool_name.c_str(), &m_ioctx);
1020 if (ret) {
1021 destroy_one_ec_pool(m_pool_name, &m_cluster);
1022 ostringstream oss;
1023 oss << "rados_ioctx_create failed: error " << ret;
1024 return oss.str();
1025 }
1026 m_init = true;
1027 return "";
1028 }
1029
1030 rados_t m_cluster;
1031 rados_ioctx_t m_ioctx;
1032 std::string m_pool_name;
1033 bool m_init;
1034 };
1035
1036 TEST(LibRadosAioEC, SimpleWrite) {
1037 AioTestDataEC test_data;
1038 rados_completion_t my_completion;
1039 ASSERT_EQ("", test_data.init());
1040 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1041 nullptr, nullptr, &my_completion));
1042 auto sg = make_scope_guard([&] { rados_aio_release(my_completion); });
1043 char buf[128];
1044 memset(buf, 0xcc, sizeof(buf));
1045 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1046 my_completion, buf, sizeof(buf), 0));
1047 {
1048 TestAlarm alarm;
1049 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1050 }
1051 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1052
1053 rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
1054 rados_completion_t my_completion2;
1055 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1056 nullptr, nullptr, &my_completion2));
1057 auto sg2 = make_scope_guard([&] { rados_aio_release(my_completion2); });
1058 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1059 my_completion2, buf, sizeof(buf), 0));
1060 {
1061 TestAlarm alarm;
1062 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1063 }
1064 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
1065 }
1066
1067 TEST(LibRadosAioEC, WaitForSafe) {
1068 AioTestDataEC test_data;
1069 rados_completion_t my_completion;
1070 ASSERT_EQ("", test_data.init());
1071 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1072 nullptr, nullptr, &my_completion));
1073 char buf[128];
1074 memset(buf, 0xcc, sizeof(buf));
1075 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1076 my_completion, buf, sizeof(buf), 0));
1077 TestAlarm alarm;
1078 ASSERT_EQ(0, rados_aio_wait_for_safe(my_completion));
1079 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1080 rados_aio_release(my_completion);
1081 }
1082
1083 TEST(LibRadosAioEC, RoundTrip) {
1084 AioTestDataEC test_data;
1085 rados_completion_t my_completion;
1086 ASSERT_EQ("", test_data.init());
1087 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1088 nullptr, nullptr, &my_completion));
1089 char buf[128];
1090 memset(buf, 0xcc, sizeof(buf));
1091 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1092 my_completion, buf, sizeof(buf), 0));
1093 {
1094 TestAlarm alarm;
1095 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1096 }
1097 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1098 char buf2[256];
1099 memset(buf2, 0, sizeof(buf2));
1100 rados_completion_t my_completion2;
1101 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1102 nullptr, nullptr, &my_completion2));
1103 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1104 my_completion2, buf2, sizeof(buf2), 0));
1105 {
1106 TestAlarm alarm;
1107 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1108 }
1109 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
1110 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
1111 rados_aio_release(my_completion);
1112 rados_aio_release(my_completion2);
1113 }
1114
1115 TEST(LibRadosAioEC, RoundTrip2) {
1116 AioTestDataEC test_data;
1117 rados_completion_t my_completion;
1118 ASSERT_EQ("", test_data.init());
1119 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1120 nullptr, nullptr, &my_completion));
1121 char buf[128];
1122 memset(buf, 0xcc, sizeof(buf));
1123 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1124 my_completion, buf, sizeof(buf), 0));
1125 {
1126 TestAlarm alarm;
1127 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1128 }
1129 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1130 char buf2[128];
1131 memset(buf2, 0, sizeof(buf2));
1132 rados_completion_t my_completion2;
1133 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1134 nullptr, nullptr, &my_completion2));
1135 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1136 my_completion2, buf2, sizeof(buf2), 0));
1137 {
1138 TestAlarm alarm;
1139 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1140 }
1141 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
1142 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
1143 rados_aio_release(my_completion);
1144 rados_aio_release(my_completion2);
1145 }
1146
1147 TEST(LibRadosAioEC, RoundTripAppend) {
1148 AioTestDataEC test_data;
1149 rados_completion_t my_completion, my_completion2, my_completion3, my_completion4;
1150 ASSERT_EQ("", test_data.init());
1151 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1152 nullptr, nullptr, &my_completion));
1153 int requires;
1154 ASSERT_EQ(0, rados_ioctx_pool_requires_alignment2(test_data.m_ioctx, &requires));
1155 ASSERT_NE(0, requires);
1156 uint64_t alignment;
1157 ASSERT_EQ(0, rados_ioctx_pool_required_alignment2(test_data.m_ioctx, &alignment));
1158 ASSERT_NE(0U, alignment);
1159
1160 int bsize = alignment;
1161 char *buf = (char *)new char[bsize];
1162 memset(buf, 0xcc, bsize);
1163 ASSERT_EQ(0, rados_aio_append(test_data.m_ioctx, "foo",
1164 my_completion, buf, bsize));
1165 {
1166 TestAlarm alarm;
1167 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1168 }
1169 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1170
1171 int hbsize = bsize / 2;
1172 char *buf2 = (char *)new char[hbsize];
1173 memset(buf2, 0xdd, hbsize);
1174 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1175 nullptr, nullptr, &my_completion2));
1176 ASSERT_EQ(0, rados_aio_append(test_data.m_ioctx, "foo",
1177 my_completion2, buf2, hbsize));
1178 {
1179 TestAlarm alarm;
1180 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1181 }
1182 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
1183
1184 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1185 nullptr, nullptr, &my_completion3));
1186 ASSERT_EQ(0, rados_aio_append(test_data.m_ioctx, "foo",
1187 my_completion3, buf2, hbsize));
1188 {
1189 TestAlarm alarm;
1190 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
1191 }
1192 EXPECT_EQ(-EOPNOTSUPP, rados_aio_get_return_value(my_completion3));
1193
1194 int tbsize = bsize + hbsize;
1195 char *buf3 = (char *)new char[tbsize];
1196 memset(buf3, 0, tbsize);
1197 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1198 nullptr, nullptr, &my_completion4));
1199 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1200 my_completion4, buf3, bsize * 3, 0));
1201 {
1202 TestAlarm alarm;
1203 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4));
1204 }
1205 ASSERT_EQ(tbsize, rados_aio_get_return_value(my_completion4));
1206 ASSERT_EQ(0, memcmp(buf3, buf, bsize));
1207 ASSERT_EQ(0, memcmp(buf3 + bsize, buf2, hbsize));
1208 rados_aio_release(my_completion);
1209 rados_aio_release(my_completion2);
1210 rados_aio_release(my_completion3);
1211 rados_aio_release(my_completion4);
1212 delete[] buf;
1213 delete[] buf2;
1214 delete[] buf3;
1215 }
1216
1217 TEST(LibRadosAioEC, IsComplete) {
1218 AioTestDataEC test_data;
1219 rados_completion_t my_completion;
1220 ASSERT_EQ("", test_data.init());
1221 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1222 nullptr, nullptr, &my_completion));
1223 char buf[128];
1224 memset(buf, 0xcc, sizeof(buf));
1225 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1226 my_completion, buf, sizeof(buf), 0));
1227 {
1228 TestAlarm alarm;
1229 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1230 }
1231 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1232 char buf2[128];
1233 memset(buf2, 0, sizeof(buf2));
1234 rados_completion_t my_completion2;
1235 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1236 nullptr, nullptr, &my_completion2));
1237 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1238 my_completion2, buf2, sizeof(buf2), 0));
1239 {
1240 TestAlarm alarm;
1241
1242 // Busy-wait until the AIO completes.
1243 // Normally we wouldn't do this, but we want to test rados_aio_is_complete.
1244 while (true) {
1245 int is_complete = rados_aio_is_complete(my_completion2);
1246 if (is_complete)
1247 break;
1248 }
1249 }
1250 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
1251 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
1252 rados_aio_release(my_completion);
1253 rados_aio_release(my_completion2);
1254 }
1255
1256 TEST(LibRadosAioEC, IsSafe) {
1257 AioTestDataEC test_data;
1258 rados_completion_t my_completion;
1259 ASSERT_EQ("", test_data.init());
1260 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1261 nullptr, nullptr, &my_completion));
1262 char buf[128];
1263 memset(buf, 0xcc, sizeof(buf));
1264 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1265 my_completion, buf, sizeof(buf), 0));
1266 {
1267 TestAlarm alarm;
1268
1269 // Busy-wait until the AIO completes.
1270 // Normally we wouldn't do this, but we want to test rados_aio_is_safe.
1271 while (true) {
1272 int is_safe = rados_aio_is_safe(my_completion);
1273 if (is_safe)
1274 break;
1275 }
1276 }
1277 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1278 char buf2[128];
1279 memset(buf2, 0, sizeof(buf2));
1280 rados_completion_t my_completion2;
1281 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1282 nullptr, nullptr, &my_completion2));
1283 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1284 my_completion2, buf2, sizeof(buf2), 0));
1285 {
1286 TestAlarm alarm;
1287 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1288 }
1289 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion2));
1290 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
1291 rados_aio_release(my_completion);
1292 rados_aio_release(my_completion2);
1293 }
1294
1295 TEST(LibRadosAioEC, ReturnValue) {
1296 AioTestDataEC test_data;
1297 rados_completion_t my_completion;
1298 ASSERT_EQ("", test_data.init());
1299 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1300 nullptr, nullptr, &my_completion));
1301 char buf[128];
1302 memset(buf, 0, sizeof(buf));
1303 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "nonexistent",
1304 my_completion, buf, sizeof(buf), 0));
1305 {
1306 TestAlarm alarm;
1307 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1308 }
1309 ASSERT_EQ(-ENOENT, rados_aio_get_return_value(my_completion));
1310 rados_aio_release(my_completion);
1311 }
1312
1313 TEST(LibRadosAioEC, Flush) {
1314 AioTestDataEC test_data;
1315 rados_completion_t my_completion;
1316 ASSERT_EQ("", test_data.init());
1317 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1318 nullptr, nullptr, &my_completion));
1319 char buf[128];
1320 memset(buf, 0xee, sizeof(buf));
1321 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1322 my_completion, buf, sizeof(buf), 0));
1323 ASSERT_EQ(0, rados_aio_flush(test_data.m_ioctx));
1324 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1325 char buf2[128];
1326 memset(buf2, 0, sizeof(buf2));
1327 rados_completion_t my_completion2;
1328 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1329 nullptr, nullptr, &my_completion2));
1330 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1331 my_completion2, buf2, sizeof(buf2), 0));
1332 {
1333 TestAlarm alarm;
1334 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1335 }
1336 ASSERT_EQ((int)sizeof(buf2), rados_aio_get_return_value(my_completion2));
1337 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
1338 rados_aio_release(my_completion);
1339 rados_aio_release(my_completion2);
1340 }
1341
1342 TEST(LibRadosAioEC, FlushAsync) {
1343 AioTestDataEC test_data;
1344 rados_completion_t my_completion;
1345 ASSERT_EQ("", test_data.init());
1346 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1347 nullptr, nullptr, &my_completion));
1348 rados_completion_t flush_completion;
1349 ASSERT_EQ(0, rados_aio_create_completion(NULL, NULL, NULL, &flush_completion));
1350 char buf[128];
1351 memset(buf, 0xee, sizeof(buf));
1352 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1353 my_completion, buf, sizeof(buf), 0));
1354 ASSERT_EQ(0, rados_aio_flush_async(test_data.m_ioctx, flush_completion));
1355 {
1356 TestAlarm alarm;
1357 ASSERT_EQ(0, rados_aio_wait_for_complete(flush_completion));
1358 ASSERT_EQ(0, rados_aio_wait_for_safe(flush_completion));
1359 }
1360 ASSERT_EQ(1, rados_aio_is_complete(my_completion));
1361 ASSERT_EQ(1, rados_aio_is_safe(my_completion));
1362 ASSERT_EQ(1, rados_aio_is_complete(flush_completion));
1363 ASSERT_EQ(1, rados_aio_is_safe(flush_completion));
1364 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1365 char buf2[128];
1366 memset(buf2, 0, sizeof(buf2));
1367 rados_completion_t my_completion2;
1368 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1369 nullptr, nullptr, &my_completion2));
1370 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1371 my_completion2, buf2, sizeof(buf2), 0));
1372 {
1373 TestAlarm alarm;
1374 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1375 }
1376 ASSERT_EQ((int)sizeof(buf2), rados_aio_get_return_value(my_completion2));
1377 ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)));
1378 rados_aio_release(my_completion);
1379 rados_aio_release(my_completion2);
1380 rados_aio_release(flush_completion);
1381 }
1382
1383 TEST(LibRadosAioEC, RoundTripWriteFull) {
1384 AioTestDataEC test_data;
1385 rados_completion_t my_completion, my_completion2, my_completion3;
1386 ASSERT_EQ("", test_data.init());
1387 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1388 nullptr, nullptr, &my_completion));
1389 char buf[128];
1390 memset(buf, 0xcc, sizeof(buf));
1391 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1392 my_completion, buf, sizeof(buf), 0));
1393 {
1394 TestAlarm alarm;
1395 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1396 }
1397 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1398 char buf2[64];
1399 memset(buf2, 0xdd, sizeof(buf2));
1400 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1401 nullptr, nullptr, &my_completion2));
1402 ASSERT_EQ(0, rados_aio_write_full(test_data.m_ioctx, "foo",
1403 my_completion2, buf2, sizeof(buf2)));
1404 {
1405 TestAlarm alarm;
1406 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1407 }
1408 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
1409 char buf3[sizeof(buf) + sizeof(buf2)];
1410 memset(buf3, 0, sizeof(buf3));
1411 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1412 nullptr, nullptr, &my_completion3));
1413 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1414 my_completion3, buf3, sizeof(buf3), 0));
1415 {
1416 TestAlarm alarm;
1417 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
1418 }
1419 ASSERT_EQ((int)sizeof(buf2), rados_aio_get_return_value(my_completion3));
1420 ASSERT_EQ(0, memcmp(buf3, buf2, sizeof(buf2)));
1421 rados_aio_release(my_completion);
1422 rados_aio_release(my_completion2);
1423 rados_aio_release(my_completion3);
1424 }
1425
1426 TEST(LibRadosAioEC, SimpleStat) {
1427 AioTestDataEC test_data;
1428 rados_completion_t my_completion;
1429 ASSERT_EQ("", test_data.init());
1430 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1431 nullptr, nullptr, &my_completion));
1432 char buf[128];
1433 memset(buf, 0xcc, sizeof(buf));
1434 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1435 my_completion, buf, sizeof(buf), 0));
1436 {
1437 TestAlarm alarm;
1438 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1439 }
1440 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1441 uint64_t psize;
1442 time_t pmtime;
1443 rados_completion_t my_completion2;
1444 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1445 nullptr, nullptr, &my_completion2));
1446 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
1447 my_completion2, &psize, &pmtime));
1448 {
1449 TestAlarm alarm;
1450 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1451 }
1452 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
1453 ASSERT_EQ(sizeof(buf), psize);
1454 rados_aio_release(my_completion);
1455 rados_aio_release(my_completion2);
1456 }
1457
1458
1459 TEST(LibRadosAioEC, SimpleStatNS) {
1460 AioTestDataEC test_data;
1461 rados_completion_t my_completion;
1462 ASSERT_EQ("", test_data.init());
1463 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1464 nullptr, nullptr, &my_completion));
1465 char buf[128];
1466 memset(buf, 0xcc, sizeof(buf));
1467 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1468 my_completion, buf, sizeof(buf), 0));
1469 {
1470 TestAlarm alarm;
1471 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1472 }
1473 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1474 rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
1475 char buf2[64];
1476 memset(buf2, 0xbb, sizeof(buf2));
1477 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1478 nullptr, nullptr, &my_completion));
1479 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1480 my_completion, buf2, sizeof(buf2), 0));
1481 {
1482 TestAlarm alarm;
1483 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1484 }
1485 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1486 uint64_t psize;
1487 time_t pmtime;
1488 rados_completion_t my_completion2;
1489 rados_ioctx_set_namespace(test_data.m_ioctx, "");
1490 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1491 nullptr, nullptr, &my_completion2));
1492 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
1493 my_completion2, &psize, &pmtime));
1494 {
1495 TestAlarm alarm;
1496 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1497 }
1498 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
1499 ASSERT_EQ(sizeof(buf), psize);
1500
1501 rados_ioctx_set_namespace(test_data.m_ioctx, "nspace");
1502 rados_completion_t my_completion3;
1503 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1504 nullptr, nullptr, &my_completion3));
1505 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
1506 my_completion3, &psize, &pmtime));
1507 {
1508 TestAlarm alarm;
1509 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
1510 }
1511 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3));
1512 ASSERT_EQ(sizeof(buf2), psize);
1513
1514 rados_aio_release(my_completion);
1515 rados_aio_release(my_completion2);
1516 rados_aio_release(my_completion3);
1517 }
1518
1519 TEST(LibRadosAioEC, StatRemove) {
1520 AioTestDataEC test_data;
1521 rados_completion_t my_completion;
1522 ASSERT_EQ("", test_data.init());
1523 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1524 nullptr, nullptr, &my_completion));
1525 char buf[128];
1526 memset(buf, 0xcc, sizeof(buf));
1527 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1528 my_completion, buf, sizeof(buf), 0));
1529 {
1530 TestAlarm alarm;
1531 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1532 }
1533 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1534 uint64_t psize;
1535 time_t pmtime;
1536 rados_completion_t my_completion2;
1537 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1538 nullptr, nullptr, &my_completion2));
1539 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
1540 my_completion2, &psize, &pmtime));
1541 {
1542 TestAlarm alarm;
1543 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1544 }
1545 ASSERT_EQ(0, rados_aio_get_return_value(my_completion2));
1546 ASSERT_EQ(sizeof(buf), psize);
1547 rados_completion_t my_completion3;
1548 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1549 nullptr, nullptr, &my_completion3));
1550 ASSERT_EQ(0, rados_aio_remove(test_data.m_ioctx, "foo", my_completion3));
1551 {
1552 TestAlarm alarm;
1553 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
1554 }
1555 ASSERT_EQ(0, rados_aio_get_return_value(my_completion3));
1556 uint64_t psize2;
1557 time_t pmtime2;
1558 rados_completion_t my_completion4;
1559 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1560 nullptr, nullptr, &my_completion4));
1561 ASSERT_EQ(0, rados_aio_stat(test_data.m_ioctx, "foo",
1562 my_completion4, &psize2, &pmtime2));
1563 {
1564 TestAlarm alarm;
1565 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion4));
1566 }
1567 ASSERT_EQ(-ENOENT, rados_aio_get_return_value(my_completion4));
1568 rados_aio_release(my_completion);
1569 rados_aio_release(my_completion2);
1570 rados_aio_release(my_completion3);
1571 rados_aio_release(my_completion4);
1572 }
1573
1574 TEST(LibRadosAioEC, ExecuteClass) {
1575 AioTestDataEC test_data;
1576 rados_completion_t my_completion;
1577 ASSERT_EQ("", test_data.init());
1578 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1579 nullptr, nullptr, &my_completion));
1580 char buf[128];
1581 memset(buf, 0xcc, sizeof(buf));
1582 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1583 my_completion, buf, sizeof(buf), 0));
1584 {
1585 TestAlarm alarm;
1586 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1587 }
1588 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1589 rados_completion_t my_completion2;
1590 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1591 nullptr, nullptr, &my_completion2));
1592 char out[128];
1593 ASSERT_EQ(0, rados_aio_exec(test_data.m_ioctx, "foo", my_completion2,
1594 "hello", "say_hello", NULL, 0, out, sizeof(out)));
1595 {
1596 TestAlarm alarm;
1597 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1598 }
1599 ASSERT_EQ(13, rados_aio_get_return_value(my_completion2));
1600 ASSERT_EQ(0, strncmp("Hello, world!", out, 13));
1601 rados_aio_release(my_completion);
1602 rados_aio_release(my_completion2);
1603 }
1604
1605 TEST(LibRadosAioEC, MultiWrite) {
1606 AioTestDataEC test_data;
1607 rados_completion_t my_completion, my_completion2, my_completion3;
1608 ASSERT_EQ("", test_data.init());
1609 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1610 nullptr, nullptr, &my_completion));
1611 char buf[128];
1612 memset(buf, 0xcc, sizeof(buf));
1613 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1614 my_completion, buf, sizeof(buf), 0));
1615 {
1616 TestAlarm alarm;
1617 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion));
1618 }
1619 ASSERT_EQ(0, rados_aio_get_return_value(my_completion));
1620
1621 char buf2[64];
1622 memset(buf2, 0xdd, sizeof(buf2));
1623 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1624 nullptr, nullptr, &my_completion2));
1625 ASSERT_EQ(0, rados_aio_write(test_data.m_ioctx, "foo",
1626 my_completion2, buf2, sizeof(buf2), sizeof(buf)));
1627 {
1628 TestAlarm alarm;
1629 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion2));
1630 }
1631 ASSERT_EQ(-EOPNOTSUPP, rados_aio_get_return_value(my_completion2));
1632
1633 char buf3[(sizeof(buf) + sizeof(buf2)) * 3];
1634 memset(buf3, 0, sizeof(buf3));
1635 ASSERT_EQ(0, rados_aio_create_completion(nullptr,
1636 nullptr, nullptr, &my_completion3));
1637 ASSERT_EQ(0, rados_aio_read(test_data.m_ioctx, "foo",
1638 my_completion3, buf3, sizeof(buf3), 0));
1639 {
1640 TestAlarm alarm;
1641 ASSERT_EQ(0, rados_aio_wait_for_complete(my_completion3));
1642 }
1643 ASSERT_EQ((int)sizeof(buf), rados_aio_get_return_value(my_completion3));
1644 ASSERT_EQ(0, memcmp(buf3, buf, sizeof(buf)));
1645 rados_aio_release(my_completion);
1646 rados_aio_release(my_completion2);
1647 rados_aio_release(my_completion3);
1648 }