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