]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/test/unit/lib/blobfs/blobfs_async_ut/blobfs_async_ut.c
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / spdk / test / unit / lib / blobfs / blobfs_async_ut / blobfs_async_ut.c
1 /*-
2 * BSD LICENSE
3 *
4 * Copyright (c) Intel Corporation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include "spdk/stdinc.h"
35
36 #include "CUnit/Basic.h"
37
38 #include "common/lib/test_env.c"
39
40 #include "spdk_cunit.h"
41 #include "blobfs/blobfs.c"
42 #include "blobfs/tree.c"
43
44 #include "unit/lib/blob/bs_dev_common.c"
45
46 struct spdk_filesystem *g_fs;
47 struct spdk_file *g_file;
48 int g_fserrno;
49
50 /* Return NULL to test hardcoded defaults. */
51 struct spdk_conf_section *
52 spdk_conf_find_section(struct spdk_conf *cp, const char *name)
53 {
54 return NULL;
55 }
56
57 /* Return -1 to test hardcoded defaults. */
58 int
59 spdk_conf_section_get_intval(struct spdk_conf_section *sp, const char *key)
60 {
61 return -1;
62 }
63
64 static void
65 _fs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
66 {
67 fn(ctx);
68 }
69
70 static void
71 fs_op_complete(void *ctx, int fserrno)
72 {
73 g_fserrno = fserrno;
74 }
75
76 static void
77 fs_op_with_handle_complete(void *ctx, struct spdk_filesystem *fs, int fserrno)
78 {
79 g_fs = fs;
80 g_fserrno = fserrno;
81 }
82
83 static void
84 fs_init(void)
85 {
86 struct spdk_filesystem *fs;
87 struct spdk_bs_dev *dev;
88
89 dev = init_dev();
90 spdk_allocate_thread(_fs_send_msg, NULL, NULL, NULL, "thread0");
91
92 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
93 SPDK_CU_ASSERT_FATAL(g_fs != NULL);
94 CU_ASSERT(g_fserrno == 0);
95 fs = g_fs;
96
97 g_fserrno = 1;
98 spdk_fs_unload(fs, fs_op_complete, NULL);
99 CU_ASSERT(g_fserrno == 0);
100
101 spdk_free_thread();
102 }
103
104 static void
105 create_cb(void *ctx, int fserrno)
106 {
107 g_fserrno = fserrno;
108 }
109
110 static void
111 open_cb(void *ctx, struct spdk_file *f, int fserrno)
112 {
113 g_fserrno = fserrno;
114 g_file = f;
115 }
116
117 static void
118 delete_cb(void *ctx, int fserrno)
119 {
120 g_fserrno = fserrno;
121 }
122
123 static void
124 fs_open(void)
125 {
126 struct spdk_filesystem *fs;
127 spdk_fs_iter iter;
128 struct spdk_bs_dev *dev;
129 struct spdk_file *file;
130 char name[257] = {'\0'};
131
132 dev = init_dev();
133 memset(name, 'a', sizeof(name) - 1);
134 spdk_allocate_thread(_fs_send_msg, NULL, NULL, NULL, "thread0");
135
136 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
137 SPDK_CU_ASSERT_FATAL(g_fs != NULL);
138 CU_ASSERT(g_fserrno == 0);
139 fs = g_fs;
140
141 g_fserrno = 0;
142 /* Open should fail, because the file name is too long. */
143 spdk_fs_open_file_async(fs, name, SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL);
144 CU_ASSERT(g_fserrno == -ENAMETOOLONG);
145
146 g_fserrno = 0;
147 spdk_fs_open_file_async(fs, "file1", 0, open_cb, NULL);
148 CU_ASSERT(g_fserrno == -ENOENT);
149
150 g_file = NULL;
151 g_fserrno = 1;
152 spdk_fs_open_file_async(fs, "file1", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL);
153 CU_ASSERT(g_fserrno == 0);
154 SPDK_CU_ASSERT_FATAL(g_file != NULL);
155 CU_ASSERT(!strcmp("file1", g_file->name));
156 CU_ASSERT(g_file->ref_count == 1);
157
158 iter = spdk_fs_iter_first(fs);
159 CU_ASSERT(iter != NULL);
160 file = spdk_fs_iter_get_file(iter);
161 SPDK_CU_ASSERT_FATAL(file != NULL);
162 CU_ASSERT(!strcmp("file1", file->name));
163 iter = spdk_fs_iter_next(iter);
164 CU_ASSERT(iter == NULL);
165
166 g_fserrno = 0;
167 /* Delete should successful, we will mark the file as deleted. */
168 spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL);
169 CU_ASSERT(g_fserrno == 0);
170 CU_ASSERT(!TAILQ_EMPTY(&fs->files));
171
172 g_fserrno = 1;
173 spdk_file_close_async(g_file, fs_op_complete, NULL);
174 CU_ASSERT(g_fserrno == 0);
175 CU_ASSERT(TAILQ_EMPTY(&fs->files));
176
177 g_fserrno = 1;
178 spdk_fs_unload(fs, fs_op_complete, NULL);
179 CU_ASSERT(g_fserrno == 0);
180
181 spdk_free_thread();
182 }
183
184 static void
185 fs_create(void)
186 {
187 struct spdk_filesystem *fs;
188 struct spdk_bs_dev *dev;
189 char name[257] = {'\0'};
190
191 dev = init_dev();
192 memset(name, 'a', sizeof(name) - 1);
193 spdk_allocate_thread(_fs_send_msg, NULL, NULL, NULL, "thread0");
194
195 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
196 SPDK_CU_ASSERT_FATAL(g_fs != NULL);
197 CU_ASSERT(g_fserrno == 0);
198 fs = g_fs;
199
200 g_fserrno = 0;
201 /* Create should fail, because the file name is too long. */
202 spdk_fs_create_file_async(fs, name, create_cb, NULL);
203 CU_ASSERT(g_fserrno == -ENAMETOOLONG);
204
205 g_fserrno = 1;
206 spdk_fs_create_file_async(fs, "file1", create_cb, NULL);
207 CU_ASSERT(g_fserrno == 0);
208
209 g_fserrno = 1;
210 spdk_fs_create_file_async(fs, "file1", create_cb, NULL);
211 CU_ASSERT(g_fserrno == -EEXIST);
212
213 g_fserrno = 1;
214 spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL);
215 CU_ASSERT(g_fserrno == 0);
216 CU_ASSERT(TAILQ_EMPTY(&fs->files));
217
218 g_fserrno = 1;
219 spdk_fs_unload(fs, fs_op_complete, NULL);
220 CU_ASSERT(g_fserrno == 0);
221
222 spdk_free_thread();
223 }
224
225 static void
226 fs_truncate(void)
227 {
228 struct spdk_filesystem *fs;
229 struct spdk_bs_dev *dev;
230
231 dev = init_dev();
232 spdk_allocate_thread(_fs_send_msg, NULL, NULL, NULL, "thread0");
233
234 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
235 SPDK_CU_ASSERT_FATAL(g_fs != NULL);
236 CU_ASSERT(g_fserrno == 0);
237 fs = g_fs;
238
239 g_file = NULL;
240 g_fserrno = 1;
241 spdk_fs_open_file_async(fs, "file1", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL);
242 CU_ASSERT(g_fserrno == 0);
243 SPDK_CU_ASSERT_FATAL(g_file != NULL);
244
245 g_fserrno = 1;
246 spdk_file_truncate_async(g_file, 18 * 1024 * 1024 + 1, fs_op_complete, NULL);
247 CU_ASSERT(g_fserrno == 0);
248 CU_ASSERT(g_file->length == 18 * 1024 * 1024 + 1);
249
250 g_fserrno = 1;
251 spdk_file_truncate_async(g_file, 1, fs_op_complete, NULL);
252 CU_ASSERT(g_fserrno == 0);
253 CU_ASSERT(g_file->length == 1);
254
255 g_fserrno = 1;
256 spdk_file_truncate_async(g_file, 18 * 1024 * 1024 + 1, fs_op_complete, NULL);
257 CU_ASSERT(g_fserrno == 0);
258 CU_ASSERT(g_file->length == 18 * 1024 * 1024 + 1);
259
260 g_fserrno = 1;
261 spdk_file_close_async(g_file, fs_op_complete, NULL);
262 CU_ASSERT(g_fserrno == 0);
263 CU_ASSERT(g_file->ref_count == 0);
264
265 g_fserrno = 1;
266 spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL);
267 CU_ASSERT(g_fserrno == 0);
268 CU_ASSERT(TAILQ_EMPTY(&fs->files));
269
270 g_fserrno = 1;
271 spdk_fs_unload(fs, fs_op_complete, NULL);
272 CU_ASSERT(g_fserrno == 0);
273
274 spdk_free_thread();
275 }
276
277 static void
278 fs_rename(void)
279 {
280 struct spdk_filesystem *fs;
281 struct spdk_file *file, *file2;
282 struct spdk_bs_dev *dev;
283
284 dev = init_dev();
285 spdk_allocate_thread(_fs_send_msg, NULL, NULL, NULL, "thread0");
286
287 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
288 SPDK_CU_ASSERT_FATAL(g_fs != NULL);
289 CU_ASSERT(g_fserrno == 0);
290 fs = g_fs;
291
292 g_fserrno = 1;
293 spdk_fs_create_file_async(fs, "file1", create_cb, NULL);
294 CU_ASSERT(g_fserrno == 0);
295
296 g_file = NULL;
297 g_fserrno = 1;
298 spdk_fs_open_file_async(fs, "file1", 0, open_cb, NULL);
299 CU_ASSERT(g_fserrno == 0);
300 SPDK_CU_ASSERT_FATAL(g_file != NULL);
301 CU_ASSERT(g_file->ref_count == 1);
302
303 file = g_file;
304 g_file = NULL;
305 g_fserrno = 1;
306 spdk_file_close_async(file, fs_op_complete, NULL);
307 CU_ASSERT(g_fserrno == 0);
308 SPDK_CU_ASSERT_FATAL(file->ref_count == 0);
309
310 g_file = NULL;
311 g_fserrno = 1;
312 spdk_fs_open_file_async(fs, "file2", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL);
313 CU_ASSERT(g_fserrno == 0);
314 SPDK_CU_ASSERT_FATAL(g_file != NULL);
315 CU_ASSERT(g_file->ref_count == 1);
316
317 file2 = g_file;
318 g_file = NULL;
319 g_fserrno = 1;
320 spdk_file_close_async(file2, fs_op_complete, NULL);
321 CU_ASSERT(g_fserrno == 0);
322 SPDK_CU_ASSERT_FATAL(file2->ref_count == 0);
323
324 /*
325 * Do a 3-way rename. This should delete the old "file2", then rename
326 * "file1" to "file2".
327 */
328 g_fserrno = 1;
329 spdk_fs_rename_file_async(fs, "file1", "file2", fs_op_complete, NULL);
330 CU_ASSERT(g_fserrno == 0);
331 CU_ASSERT(file->ref_count == 0);
332 CU_ASSERT(!strcmp(file->name, "file2"));
333 CU_ASSERT(TAILQ_FIRST(&fs->files) == file);
334 CU_ASSERT(TAILQ_NEXT(file, tailq) == NULL);
335
336 g_fserrno = 0;
337 spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL);
338 CU_ASSERT(g_fserrno == -ENOENT);
339 CU_ASSERT(!TAILQ_EMPTY(&fs->files));
340
341 g_fserrno = 1;
342 spdk_fs_delete_file_async(fs, "file2", delete_cb, NULL);
343 CU_ASSERT(g_fserrno == 0);
344 CU_ASSERT(TAILQ_EMPTY(&fs->files));
345
346 g_fserrno = 1;
347 spdk_fs_unload(fs, fs_op_complete, NULL);
348 CU_ASSERT(g_fserrno == 0);
349
350 spdk_free_thread();
351 }
352
353 static void
354 tree_find_buffer_ut(void)
355 {
356 struct cache_tree *root;
357 struct cache_tree *level1_0;
358 struct cache_tree *level0_0_0;
359 struct cache_tree *level0_0_12;
360 struct cache_buffer *leaf_0_0_4;
361 struct cache_buffer *leaf_0_12_8;
362 struct cache_buffer *leaf_9_23_15;
363 struct cache_buffer *buffer;
364
365 level1_0 = calloc(1, sizeof(struct cache_tree));
366 SPDK_CU_ASSERT_FATAL(level1_0 != NULL);
367 level0_0_0 = calloc(1, sizeof(struct cache_tree));
368 SPDK_CU_ASSERT_FATAL(level0_0_0 != NULL);
369 level0_0_12 = calloc(1, sizeof(struct cache_tree));
370 SPDK_CU_ASSERT_FATAL(level0_0_12 != NULL);
371 leaf_0_0_4 = calloc(1, sizeof(struct cache_buffer));
372 SPDK_CU_ASSERT_FATAL(leaf_0_0_4 != NULL);
373 leaf_0_12_8 = calloc(1, sizeof(struct cache_buffer));
374 SPDK_CU_ASSERT_FATAL(leaf_0_12_8 != NULL);
375 leaf_9_23_15 = calloc(1, sizeof(struct cache_buffer));
376 SPDK_CU_ASSERT_FATAL(leaf_9_23_15 != NULL);
377
378 level1_0->level = 1;
379 level0_0_0->level = 0;
380 level0_0_12->level = 0;
381
382 leaf_0_0_4->offset = CACHE_BUFFER_SIZE * 4;
383 level0_0_0->u.buffer[4] = leaf_0_0_4;
384 level0_0_0->present_mask |= (1ULL << 4);
385
386 leaf_0_12_8->offset = CACHE_TREE_LEVEL_SIZE(1) * 12 + CACHE_BUFFER_SIZE * 8;
387 level0_0_12->u.buffer[8] = leaf_0_12_8;
388 level0_0_12->present_mask |= (1ULL << 8);
389
390 level1_0->u.tree[0] = level0_0_0;
391 level1_0->present_mask |= (1ULL << 0);
392 level1_0->u.tree[12] = level0_0_12;
393 level1_0->present_mask |= (1ULL << 12);
394
395 buffer = spdk_tree_find_buffer(NULL, 0);
396 CU_ASSERT(buffer == NULL);
397
398 buffer = spdk_tree_find_buffer(level0_0_0, 0);
399 CU_ASSERT(buffer == NULL);
400
401 buffer = spdk_tree_find_buffer(level0_0_0, CACHE_TREE_LEVEL_SIZE(0) + 1);
402 CU_ASSERT(buffer == NULL);
403
404 buffer = spdk_tree_find_buffer(level0_0_0, leaf_0_0_4->offset);
405 CU_ASSERT(buffer == leaf_0_0_4);
406
407 buffer = spdk_tree_find_buffer(level1_0, leaf_0_0_4->offset);
408 CU_ASSERT(buffer == leaf_0_0_4);
409
410 buffer = spdk_tree_find_buffer(level1_0, leaf_0_12_8->offset);
411 CU_ASSERT(buffer == leaf_0_12_8);
412
413 buffer = spdk_tree_find_buffer(level1_0, leaf_0_12_8->offset + CACHE_BUFFER_SIZE - 1);
414 CU_ASSERT(buffer == leaf_0_12_8);
415
416 buffer = spdk_tree_find_buffer(level1_0, leaf_0_12_8->offset - 1);
417 CU_ASSERT(buffer == NULL);
418
419 leaf_9_23_15->offset = CACHE_TREE_LEVEL_SIZE(2) * 9 +
420 CACHE_TREE_LEVEL_SIZE(1) * 23 +
421 CACHE_BUFFER_SIZE * 15;
422 root = spdk_tree_insert_buffer(level1_0, leaf_9_23_15);
423 CU_ASSERT(root != level1_0);
424 buffer = spdk_tree_find_buffer(root, leaf_9_23_15->offset);
425 CU_ASSERT(buffer == leaf_9_23_15);
426 spdk_tree_free_buffers(root);
427 free(root);
428 }
429
430 static void
431 channel_ops(void)
432 {
433 struct spdk_filesystem *fs;
434 struct spdk_bs_dev *dev;
435 struct spdk_io_channel *channel;
436
437 dev = init_dev();
438 spdk_allocate_thread(_fs_send_msg, NULL, NULL, NULL, "thread0");
439
440 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
441 SPDK_CU_ASSERT_FATAL(g_fs != NULL);
442 CU_ASSERT(g_fserrno == 0);
443 fs = g_fs;
444
445 channel = spdk_fs_alloc_io_channel(fs);
446 CU_ASSERT(channel != NULL);
447
448 spdk_fs_free_io_channel(channel);
449
450 g_fserrno = 1;
451 spdk_fs_unload(fs, fs_op_complete, NULL);
452 CU_ASSERT(g_fserrno == 0);
453 g_fs = NULL;
454
455 spdk_free_thread();
456 }
457
458 static void
459 channel_ops_sync(void)
460 {
461 struct spdk_filesystem *fs;
462 struct spdk_bs_dev *dev;
463 struct spdk_io_channel *channel;
464
465 dev = init_dev();
466 spdk_allocate_thread(_fs_send_msg, NULL, NULL, NULL, "thread0");
467
468 spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
469 SPDK_CU_ASSERT_FATAL(g_fs != NULL);
470 CU_ASSERT(g_fserrno == 0);
471 fs = g_fs;
472
473 channel = spdk_fs_alloc_io_channel_sync(fs);
474 CU_ASSERT(channel != NULL);
475
476 spdk_fs_free_io_channel(channel);
477
478 g_fserrno = 1;
479 spdk_fs_unload(fs, fs_op_complete, NULL);
480 CU_ASSERT(g_fserrno == 0);
481 g_fs = NULL;
482
483 spdk_free_thread();
484 }
485
486 int main(int argc, char **argv)
487 {
488 CU_pSuite suite = NULL;
489 unsigned int num_failures;
490
491 if (CU_initialize_registry() != CUE_SUCCESS) {
492 return CU_get_error();
493 }
494
495 suite = CU_add_suite("blobfs_async_ut", NULL, NULL);
496 if (suite == NULL) {
497 CU_cleanup_registry();
498 return CU_get_error();
499 }
500
501 if (
502 CU_add_test(suite, "fs_init", fs_init) == NULL ||
503 CU_add_test(suite, "fs_open", fs_open) == NULL ||
504 CU_add_test(suite, "fs_create", fs_create) == NULL ||
505 CU_add_test(suite, "fs_truncate", fs_truncate) == NULL ||
506 CU_add_test(suite, "fs_rename", fs_rename) == NULL ||
507 CU_add_test(suite, "tree_find_buffer", tree_find_buffer_ut) == NULL ||
508 CU_add_test(suite, "channel_ops", channel_ops) == NULL ||
509 CU_add_test(suite, "channel_ops_sync", channel_ops_sync) == NULL
510 ) {
511 CU_cleanup_registry();
512 return CU_get_error();
513 }
514
515 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
516 CU_basic_set_mode(CU_BRM_VERBOSE);
517 CU_basic_run_tests();
518 num_failures = CU_get_number_of_failures();
519 CU_cleanup_registry();
520 free(g_dev_buffer);
521 return num_failures;
522 }