]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -* |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include <climits> | |
5 | ||
6 | #include "include/rados/librados.h" | |
7c673cae | 7 | #include "include/encoding.h" |
c07f9fc5 | 8 | #include "include/err.h" |
7c673cae FG |
9 | #include "include/scope_guard.h" |
10 | #include "test/librados/test.h" | |
11 | #include "test/librados/TestCase.h" | |
12 | ||
13 | #include <errno.h> | |
14 | #include "gtest/gtest.h" | |
15 | ||
7c673cae FG |
16 | using std::string; |
17 | ||
18 | typedef RadosTest LibRadosIo; | |
19 | typedef RadosTestEC LibRadosIoEC; | |
7c673cae FG |
20 | |
21 | TEST_F(LibRadosIo, SimpleWrite) { | |
22 | char buf[128]; | |
23 | memset(buf, 0xcc, sizeof(buf)); | |
24 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
25 | rados_ioctx_set_namespace(ioctx, "nspace"); | |
26 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
27 | } | |
28 | ||
29 | TEST_F(LibRadosIo, TooBig) { | |
30 | char buf[1]; | |
31 | ASSERT_EQ(-E2BIG, rados_write(ioctx, "A", buf, UINT_MAX, 0)); | |
32 | ASSERT_EQ(-E2BIG, rados_append(ioctx, "A", buf, UINT_MAX)); | |
33 | ASSERT_EQ(-E2BIG, rados_write_full(ioctx, "A", buf, UINT_MAX)); | |
34 | ASSERT_EQ(-E2BIG, rados_writesame(ioctx, "A", buf, sizeof(buf), UINT_MAX, 0)); | |
7c673cae FG |
35 | } |
36 | ||
37 | TEST_F(LibRadosIo, ReadTimeout) { | |
38 | char buf[128]; | |
39 | memset(buf, 'a', sizeof(buf)); | |
40 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
41 | ||
42 | { | |
43 | // set up a second client | |
44 | rados_t cluster; | |
45 | rados_ioctx_t ioctx; | |
46 | ASSERT_EQ(0, rados_create(&cluster, "admin")); | |
47 | ASSERT_EQ(0, rados_conf_read_file(cluster, NULL)); | |
48 | ASSERT_EQ(0, rados_conf_parse_env(cluster, NULL)); | |
49 | ASSERT_EQ(0, rados_conf_set(cluster, "rados_osd_op_timeout", "0.00001")); // use any small value that will result in a timeout | |
50 | ASSERT_EQ(0, rados_connect(cluster)); | |
51 | ASSERT_EQ(0, rados_ioctx_create(cluster, pool_name.c_str(), &ioctx)); | |
52 | rados_ioctx_set_namespace(ioctx, nspace.c_str()); | |
53 | ||
54 | // then we show that the buffer is changed after rados_read returned | |
55 | // with a timeout | |
56 | for (int i=0; i<5; i++) { | |
57 | char buf2[sizeof(buf)]; | |
58 | memset(buf2, 0, sizeof(buf2)); | |
59 | int err = rados_read(ioctx, "foo", buf2, sizeof(buf2), 0); | |
60 | if (err == -110) { | |
61 | int startIndex = 0; | |
62 | // find the index until which librados already read the object before the timeout occurred | |
63 | for (unsigned b=0; b<sizeof(buf); b++) { | |
64 | if (buf2[b] != buf[b]) { | |
65 | startIndex = b; | |
66 | break; | |
67 | } | |
68 | } | |
69 | ||
70 | // wait some time to give librados a change to do something | |
71 | sleep(1); | |
72 | ||
73 | // then check if the buffer was changed after the call | |
74 | if (buf2[startIndex] == 'a') { | |
75 | printf("byte at index %d was changed after the timeout to %d\n", | |
76 | startIndex, (int)buf[startIndex]); | |
77 | ASSERT_TRUE(0); | |
78 | break; | |
79 | } | |
80 | } else { | |
81 | printf("no timeout :/\n"); | |
82 | } | |
83 | } | |
84 | rados_ioctx_destroy(ioctx); | |
85 | rados_shutdown(cluster); | |
86 | } | |
87 | } | |
88 | ||
7c673cae FG |
89 | |
90 | TEST_F(LibRadosIo, RoundTrip) { | |
91 | char buf[128]; | |
92 | char buf2[128]; | |
93 | memset(buf, 0xcc, sizeof(buf)); | |
94 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
95 | memset(buf2, 0, sizeof(buf2)); | |
96 | ASSERT_EQ((int)sizeof(buf2), rados_read(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
97 | ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf))); | |
98 | ||
99 | uint64_t off = 19; | |
100 | memset(buf, 0xcc, sizeof(buf)); | |
101 | ASSERT_EQ(0, rados_write(ioctx, "bar", buf, sizeof(buf), off)); | |
102 | memset(buf2, 0, sizeof(buf2)); | |
103 | ASSERT_EQ((int)sizeof(buf2), rados_read(ioctx, "bar", buf2, sizeof(buf2), off)); | |
104 | ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf))); | |
105 | } | |
106 | ||
7c673cae FG |
107 | TEST_F(LibRadosIo, Checksum) { |
108 | char buf[128]; | |
109 | memset(buf, 0xcc, sizeof(buf)); | |
110 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
111 | ||
112 | uint32_t expected_crc = ceph_crc32c(-1, reinterpret_cast<const uint8_t*>(buf), | |
113 | sizeof(buf)); | |
114 | uint32_t init_value = -1; | |
115 | uint32_t crc[2]; | |
116 | ASSERT_EQ(0, rados_checksum(ioctx, "foo", LIBRADOS_CHECKSUM_TYPE_CRC32C, | |
117 | reinterpret_cast<char*>(&init_value), | |
118 | sizeof(init_value), sizeof(buf), 0, 0, | |
119 | reinterpret_cast<char*>(&crc), sizeof(crc))); | |
120 | ASSERT_EQ(1U, crc[0]); | |
121 | ASSERT_EQ(expected_crc, crc[1]); | |
122 | } | |
123 | ||
7c673cae FG |
124 | TEST_F(LibRadosIo, OverlappingWriteRoundTrip) { |
125 | char buf[128]; | |
126 | char buf2[64]; | |
127 | char buf3[128]; | |
128 | memset(buf, 0xcc, sizeof(buf)); | |
129 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
130 | memset(buf2, 0xdd, sizeof(buf2)); | |
131 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
132 | memset(buf3, 0xdd, sizeof(buf3)); | |
133 | ASSERT_EQ((int)sizeof(buf3), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0)); | |
134 | ASSERT_EQ(0, memcmp(buf3, buf2, sizeof(buf2))); | |
135 | ASSERT_EQ(0, memcmp(buf3 + sizeof(buf2), buf, sizeof(buf) - sizeof(buf2))); | |
136 | } | |
137 | ||
7c673cae FG |
138 | TEST_F(LibRadosIo, WriteFullRoundTrip) { |
139 | char buf[128]; | |
140 | char buf2[64]; | |
141 | char buf3[128]; | |
142 | memset(buf, 0xcc, sizeof(buf)); | |
143 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
144 | memset(buf2, 0xdd, sizeof(buf2)); | |
145 | ASSERT_EQ(0, rados_write_full(ioctx, "foo", buf2, sizeof(buf2))); | |
146 | memset(buf3, 0x00, sizeof(buf3)); | |
147 | ASSERT_EQ((int)sizeof(buf2), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0)); | |
148 | ASSERT_EQ(0, memcmp(buf2, buf3, sizeof(buf2))); | |
149 | } | |
150 | ||
7c673cae FG |
151 | TEST_F(LibRadosIo, AppendRoundTrip) { |
152 | char buf[64]; | |
153 | char buf2[64]; | |
154 | char buf3[sizeof(buf) + sizeof(buf2)]; | |
155 | memset(buf, 0xde, sizeof(buf)); | |
156 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
157 | memset(buf2, 0xad, sizeof(buf2)); | |
158 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf2, sizeof(buf2))); | |
159 | memset(buf3, 0, sizeof(buf3)); | |
160 | ASSERT_EQ((int)sizeof(buf3), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0)); | |
161 | ASSERT_EQ(0, memcmp(buf3, buf, sizeof(buf))); | |
162 | ASSERT_EQ(0, memcmp(buf3 + sizeof(buf), buf2, sizeof(buf2))); | |
163 | } | |
164 | ||
7c673cae FG |
165 | TEST_F(LibRadosIo, TruncTest) { |
166 | char buf[128]; | |
167 | char buf2[sizeof(buf)]; | |
168 | memset(buf, 0xaa, sizeof(buf)); | |
169 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
170 | ASSERT_EQ(0, rados_trunc(ioctx, "foo", sizeof(buf) / 2)); | |
171 | memset(buf2, 0, sizeof(buf2)); | |
172 | ASSERT_EQ((int)(sizeof(buf)/2), rados_read(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
173 | ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf)/2)); | |
174 | } | |
175 | ||
7c673cae FG |
176 | TEST_F(LibRadosIo, RemoveTest) { |
177 | char buf[128]; | |
178 | char buf2[sizeof(buf)]; | |
179 | memset(buf, 0xaa, sizeof(buf)); | |
180 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
181 | ASSERT_EQ(0, rados_remove(ioctx, "foo")); | |
182 | memset(buf2, 0, sizeof(buf2)); | |
183 | ASSERT_EQ(-ENOENT, rados_read(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
184 | } | |
185 | ||
7c673cae FG |
186 | TEST_F(LibRadosIo, XattrsRoundTrip) { |
187 | char buf[128]; | |
188 | char attr1[] = "attr1"; | |
189 | char attr1_buf[] = "foo bar baz"; | |
190 | memset(buf, 0xaa, sizeof(buf)); | |
191 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
192 | ASSERT_EQ(-ENODATA, rados_getxattr(ioctx, "foo", attr1, buf, sizeof(buf))); | |
193 | ASSERT_EQ(0, rados_setxattr(ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf))); | |
194 | ASSERT_EQ((int)sizeof(attr1_buf), | |
195 | rados_getxattr(ioctx, "foo", attr1, buf, sizeof(buf))); | |
196 | ASSERT_EQ(0, memcmp(attr1_buf, buf, sizeof(attr1_buf))); | |
197 | } | |
198 | ||
7c673cae FG |
199 | TEST_F(LibRadosIo, RmXattr) { |
200 | char buf[128]; | |
201 | char attr1[] = "attr1"; | |
202 | char attr1_buf[] = "foo bar baz"; | |
203 | memset(buf, 0xaa, sizeof(buf)); | |
204 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
205 | ASSERT_EQ(0, | |
206 | rados_setxattr(ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf))); | |
207 | ASSERT_EQ(0, rados_rmxattr(ioctx, "foo", attr1)); | |
208 | ASSERT_EQ(-ENODATA, rados_getxattr(ioctx, "foo", attr1, buf, sizeof(buf))); | |
209 | ||
210 | // Test rmxattr on a removed object | |
211 | char buf2[128]; | |
212 | char attr2[] = "attr2"; | |
213 | char attr2_buf[] = "foo bar baz"; | |
214 | memset(buf2, 0xbb, sizeof(buf2)); | |
215 | ASSERT_EQ(0, rados_write(ioctx, "foo_rmxattr", buf2, sizeof(buf2), 0)); | |
216 | ASSERT_EQ(0, | |
217 | rados_setxattr(ioctx, "foo_rmxattr", attr2, attr2_buf, sizeof(attr2_buf))); | |
218 | ASSERT_EQ(0, rados_remove(ioctx, "foo_rmxattr")); | |
219 | ASSERT_EQ(-ENOENT, rados_rmxattr(ioctx, "foo_rmxattr", attr2)); | |
220 | } | |
221 | ||
7c673cae FG |
222 | TEST_F(LibRadosIo, XattrIter) { |
223 | char buf[128]; | |
224 | char attr1[] = "attr1"; | |
225 | char attr1_buf[] = "foo bar baz"; | |
226 | char attr2[] = "attr2"; | |
227 | char attr2_buf[256]; | |
228 | for (size_t j = 0; j < sizeof(attr2_buf); ++j) { | |
229 | attr2_buf[j] = j % 0xff; | |
230 | } | |
231 | memset(buf, 0xaa, sizeof(buf)); | |
232 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
233 | ASSERT_EQ(0, rados_setxattr(ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf))); | |
234 | ASSERT_EQ(0, rados_setxattr(ioctx, "foo", attr2, attr2_buf, sizeof(attr2_buf))); | |
235 | rados_xattrs_iter_t iter; | |
236 | ASSERT_EQ(0, rados_getxattrs(ioctx, "foo", &iter)); | |
237 | int num_seen = 0; | |
238 | while (true) { | |
239 | const char *name; | |
240 | const char *val; | |
241 | size_t len; | |
242 | ASSERT_EQ(0, rados_getxattrs_next(iter, &name, &val, &len)); | |
243 | if (name == NULL) { | |
244 | break; | |
245 | } | |
246 | ASSERT_LT(num_seen, 2); | |
247 | if ((strcmp(name, attr1) == 0) && (val != NULL) && (memcmp(val, attr1_buf, len) == 0)) { | |
248 | num_seen++; | |
249 | continue; | |
250 | } | |
251 | else if ((strcmp(name, attr2) == 0) && (val != NULL) && (memcmp(val, attr2_buf, len) == 0)) { | |
252 | num_seen++; | |
253 | continue; | |
254 | } | |
255 | else { | |
256 | ASSERT_EQ(0, 1); | |
257 | } | |
258 | } | |
259 | rados_getxattrs_end(iter); | |
260 | } | |
261 | ||
7c673cae FG |
262 | TEST_F(LibRadosIoEC, SimpleWrite) { |
263 | char buf[128]; | |
264 | memset(buf, 0xcc, sizeof(buf)); | |
265 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
266 | rados_ioctx_set_namespace(ioctx, "nspace"); | |
267 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
268 | } | |
269 | ||
7c673cae FG |
270 | TEST_F(LibRadosIoEC, RoundTrip) { |
271 | char buf[128]; | |
272 | char buf2[128]; | |
273 | memset(buf, 0xcc, sizeof(buf)); | |
274 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
275 | memset(buf2, 0, sizeof(buf2)); | |
276 | ASSERT_EQ((int)sizeof(buf2), rados_read(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
277 | ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf))); | |
278 | ||
279 | uint64_t off = 19; | |
280 | ASSERT_EQ(-EOPNOTSUPP, rados_write(ioctx, "bar", buf, sizeof(buf), off)); | |
281 | } | |
282 | ||
7c673cae FG |
283 | TEST_F(LibRadosIoEC, OverlappingWriteRoundTrip) { |
284 | int bsize = alignment; | |
285 | int dbsize = bsize * 2; | |
286 | char *buf = (char *)new char[dbsize]; | |
287 | char *buf2 = (char *)new char[bsize]; | |
288 | char *buf3 = (char *)new char[dbsize]; | |
289 | auto cleanup = [&] { | |
290 | delete[] buf; | |
291 | delete[] buf2; | |
292 | delete[] buf3; | |
293 | }; | |
294 | scope_guard<decltype(cleanup)> sg(std::move(cleanup)); | |
295 | memset(buf, 0xcc, dbsize); | |
296 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, dbsize, 0)); | |
297 | memset(buf2, 0xdd, bsize); | |
298 | ASSERT_EQ(-EOPNOTSUPP, rados_write(ioctx, "foo", buf2, bsize, 0)); | |
299 | memset(buf3, 0xdd, dbsize); | |
300 | ASSERT_EQ(dbsize, rados_read(ioctx, "foo", buf3, dbsize, 0)); | |
301 | // Read the same as first write | |
302 | ASSERT_EQ(0, memcmp(buf3, buf, dbsize)); | |
303 | } | |
304 | ||
7c673cae FG |
305 | TEST_F(LibRadosIoEC, WriteFullRoundTrip) { |
306 | char buf[128]; | |
307 | char buf2[64]; | |
308 | char buf3[128]; | |
309 | memset(buf, 0xcc, sizeof(buf)); | |
310 | ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); | |
311 | memset(buf2, 0xdd, sizeof(buf2)); | |
312 | ASSERT_EQ(0, rados_write_full(ioctx, "foo", buf2, sizeof(buf2))); | |
313 | memset(buf3, 0xee, sizeof(buf3)); | |
314 | ASSERT_EQ((int)sizeof(buf2), rados_read(ioctx, "foo", buf3, sizeof(buf3), 0)); | |
315 | ASSERT_EQ(0, memcmp(buf3, buf2, sizeof(buf2))); | |
316 | } | |
317 | ||
7c673cae FG |
318 | TEST_F(LibRadosIoEC, AppendRoundTrip) { |
319 | char *buf = (char *)new char[alignment]; | |
320 | char *buf2 = (char *)new char[alignment]; | |
321 | char *buf3 = (char *)new char[alignment *2]; | |
322 | int uasize = alignment/2; | |
323 | char *unalignedbuf = (char *)new char[uasize]; | |
324 | auto cleanup = [&] { | |
325 | delete[] buf; | |
326 | delete[] buf2; | |
327 | delete[] buf3; | |
328 | delete[] unalignedbuf; | |
329 | }; | |
330 | scope_guard<decltype(cleanup)> sg(std::move(cleanup)); | |
331 | memset(buf, 0xde, alignment); | |
332 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, alignment)); | |
333 | memset(buf2, 0xad, alignment); | |
334 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf2, alignment)); | |
335 | memset(buf3, 0, alignment*2); | |
336 | ASSERT_EQ((int)alignment*2, rados_read(ioctx, "foo", buf3, alignment*2, 0)); | |
337 | ASSERT_EQ(0, memcmp(buf3, buf, alignment)); | |
338 | ASSERT_EQ(0, memcmp(buf3 + alignment, buf2, alignment)); | |
339 | memset(unalignedbuf, 0, uasize); | |
340 | ASSERT_EQ(0, rados_append(ioctx, "foo", unalignedbuf, uasize)); | |
341 | ASSERT_EQ(-EOPNOTSUPP, rados_append(ioctx, "foo", unalignedbuf, uasize)); | |
342 | } | |
343 | ||
7c673cae FG |
344 | TEST_F(LibRadosIoEC, TruncTest) { |
345 | char buf[128]; | |
346 | char buf2[sizeof(buf)]; | |
347 | memset(buf, 0xaa, sizeof(buf)); | |
348 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
349 | ASSERT_EQ(-EOPNOTSUPP, rados_trunc(ioctx, "foo", sizeof(buf) / 2)); | |
350 | memset(buf2, 0, sizeof(buf2)); | |
351 | // Same size | |
352 | ASSERT_EQ((int)sizeof(buf), rados_read(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
353 | // No change | |
354 | ASSERT_EQ(0, memcmp(buf, buf2, sizeof(buf))); | |
355 | } | |
356 | ||
7c673cae FG |
357 | TEST_F(LibRadosIoEC, RemoveTest) { |
358 | char buf[128]; | |
359 | char buf2[sizeof(buf)]; | |
360 | memset(buf, 0xaa, sizeof(buf)); | |
361 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
362 | ASSERT_EQ(0, rados_remove(ioctx, "foo")); | |
363 | memset(buf2, 0, sizeof(buf2)); | |
364 | ASSERT_EQ(-ENOENT, rados_read(ioctx, "foo", buf2, sizeof(buf2), 0)); | |
365 | } | |
366 | ||
7c673cae FG |
367 | TEST_F(LibRadosIoEC, XattrsRoundTrip) { |
368 | char buf[128]; | |
369 | char attr1[] = "attr1"; | |
370 | char attr1_buf[] = "foo bar baz"; | |
371 | memset(buf, 0xaa, sizeof(buf)); | |
372 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
373 | ASSERT_EQ(-ENODATA, rados_getxattr(ioctx, "foo", attr1, buf, sizeof(buf))); | |
374 | ASSERT_EQ(0, rados_setxattr(ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf))); | |
375 | ASSERT_EQ((int)sizeof(attr1_buf), | |
376 | rados_getxattr(ioctx, "foo", attr1, buf, sizeof(buf))); | |
377 | ASSERT_EQ(0, memcmp(attr1_buf, buf, sizeof(attr1_buf))); | |
378 | } | |
379 | ||
7c673cae FG |
380 | TEST_F(LibRadosIoEC, RmXattr) { |
381 | char buf[128]; | |
382 | char attr1[] = "attr1"; | |
383 | char attr1_buf[] = "foo bar baz"; | |
384 | memset(buf, 0xaa, sizeof(buf)); | |
385 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
386 | ASSERT_EQ(0, | |
387 | rados_setxattr(ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf))); | |
388 | ASSERT_EQ(0, rados_rmxattr(ioctx, "foo", attr1)); | |
389 | ASSERT_EQ(-ENODATA, rados_getxattr(ioctx, "foo", attr1, buf, sizeof(buf))); | |
390 | ||
391 | // Test rmxattr on a removed object | |
392 | char buf2[128]; | |
393 | char attr2[] = "attr2"; | |
394 | char attr2_buf[] = "foo bar baz"; | |
395 | memset(buf2, 0xbb, sizeof(buf2)); | |
396 | ASSERT_EQ(0, rados_write(ioctx, "foo_rmxattr", buf2, sizeof(buf2), 0)); | |
397 | ASSERT_EQ(0, | |
398 | rados_setxattr(ioctx, "foo_rmxattr", attr2, attr2_buf, sizeof(attr2_buf))); | |
399 | ASSERT_EQ(0, rados_remove(ioctx, "foo_rmxattr")); | |
400 | ASSERT_EQ(-ENOENT, rados_rmxattr(ioctx, "foo_rmxattr", attr2)); | |
401 | } | |
402 | ||
7c673cae FG |
403 | TEST_F(LibRadosIoEC, XattrIter) { |
404 | char buf[128]; | |
405 | char attr1[] = "attr1"; | |
406 | char attr1_buf[] = "foo bar baz"; | |
407 | char attr2[] = "attr2"; | |
408 | char attr2_buf[256]; | |
409 | for (size_t j = 0; j < sizeof(attr2_buf); ++j) { | |
410 | attr2_buf[j] = j % 0xff; | |
411 | } | |
412 | memset(buf, 0xaa, sizeof(buf)); | |
413 | ASSERT_EQ(0, rados_append(ioctx, "foo", buf, sizeof(buf))); | |
414 | ASSERT_EQ(0, rados_setxattr(ioctx, "foo", attr1, attr1_buf, sizeof(attr1_buf))); | |
415 | ASSERT_EQ(0, rados_setxattr(ioctx, "foo", attr2, attr2_buf, sizeof(attr2_buf))); | |
416 | rados_xattrs_iter_t iter; | |
417 | ASSERT_EQ(0, rados_getxattrs(ioctx, "foo", &iter)); | |
418 | int num_seen = 0; | |
419 | while (true) { | |
420 | const char *name; | |
421 | const char *val; | |
422 | size_t len; | |
423 | ASSERT_EQ(0, rados_getxattrs_next(iter, &name, &val, &len)); | |
424 | if (name == NULL) { | |
425 | break; | |
426 | } | |
427 | ASSERT_LT(num_seen, 2); | |
428 | if ((strcmp(name, attr1) == 0) && (val != NULL) && (memcmp(val, attr1_buf, len) == 0)) { | |
429 | num_seen++; | |
430 | continue; | |
431 | } | |
432 | else if ((strcmp(name, attr2) == 0) && (val != NULL) && (memcmp(val, attr2_buf, len) == 0)) { | |
433 | num_seen++; | |
434 | continue; | |
435 | } | |
436 | else { | |
437 | ASSERT_EQ(0, 1); | |
438 | } | |
439 | } | |
440 | rados_getxattrs_end(iter); | |
441 | } |