]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/test/lib/blobfs/blobfs_ut/blobfs_ut.c
bump version to 12.2.12-pve1
[ceph.git] / ceph / src / spdk / test / lib / blobfs / blobfs_ut / blobfs_ut.c
CommitLineData
7c673cae
FG
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 <stdlib.h>
35#include <unistd.h>
36#include <errno.h>
37#include <stdio.h>
38
39#include "CUnit/Basic.h"
40
41#include "lib/test_env.c"
42
43#include "spdk_cunit.h"
44#include "blobfs.c"
45#include "tree.c"
46
47#include "lib/blob/bs_dev_common.c"
48
49struct spdk_filesystem *g_fs;
50struct spdk_file *g_file;
51int g_fserrno;
52
53static void
54fs_op_complete(void *ctx, int fserrno)
55{
56 g_fserrno = fserrno;
57}
58
59static void
60fs_op_with_handle_complete(void *ctx, struct spdk_filesystem *fs, int fserrno)
61{
62 g_fs = fs;
63 g_fserrno = fserrno;
64}
65
66static void
67fs_init(void)
68{
69 struct spdk_filesystem *fs;
70 struct spdk_bs_dev dev;
71
72 init_dev(&dev);
73 spdk_allocate_thread();
74
75 spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
76 CU_ASSERT(g_fs != NULL);
77 CU_ASSERT(g_fserrno == 0);
78 fs = g_fs;
79
80 spdk_fs_unload(fs, fs_op_complete, NULL);
81 CU_ASSERT(g_fserrno == 0);
82
83 spdk_free_thread();
84}
85
86static void
87create_cb(void *ctx, int fserrno)
88{
89 g_fserrno = fserrno;
90}
91
92static void
93open_cb(void *ctx, struct spdk_file *f, int fserrno)
94{
95 g_fserrno = fserrno;
96 g_file = f;
97}
98
99static void
100delete_cb(void *ctx, int fserrno)
101{
102 g_fserrno = fserrno;
103}
104
105static void
106fs_open(void)
107{
108 struct spdk_filesystem *fs;
109 spdk_fs_iter iter;
110 struct spdk_bs_dev dev;
111 struct spdk_file *file;
112
113 init_dev(&dev);
114 spdk_allocate_thread();
115
116 spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
117 CU_ASSERT(g_fs != NULL);
118 CU_ASSERT(g_fserrno == 0);
119 fs = g_fs;
120
121 g_fserrno = 0;
122 spdk_fs_open_file_async(fs, "file1", 0, open_cb, NULL);
123 CU_ASSERT(g_fserrno == -ENOENT);
124
125 g_file = NULL;
126 g_fserrno = 1;
127 spdk_fs_open_file_async(fs, "file1", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL);
128 CU_ASSERT(g_fserrno == 0);
129 SPDK_CU_ASSERT_FATAL(g_file != NULL);
130 CU_ASSERT(!strcmp("file1", g_file->name));
131 CU_ASSERT(g_file->ref_count == 1);
132
133 iter = spdk_fs_iter_first(fs);
134 CU_ASSERT(iter != NULL);
135 file = spdk_fs_iter_get_file(iter);
136 SPDK_CU_ASSERT_FATAL(file != NULL);
137 CU_ASSERT(!strcmp("file1", file->name));
138 iter = spdk_fs_iter_next(iter);
139 CU_ASSERT(iter == NULL);
140
141 g_fserrno = 0;
142 /* Delete should fail, since we have an open reference. */
143 spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL);
144 CU_ASSERT(g_fserrno == -EBUSY);
145 CU_ASSERT(!TAILQ_EMPTY(&fs->files));
146
147 g_fserrno = 1;
148 spdk_file_close_async(g_file, fs_op_complete, NULL);
149 CU_ASSERT(g_fserrno == 0);
150 CU_ASSERT(g_file->ref_count == 0);
151
152 g_fserrno = 0;
153 spdk_file_close_async(g_file, fs_op_complete, NULL);
154 CU_ASSERT(g_fserrno == -EBADF);
155 CU_ASSERT(g_file->ref_count == 0);
156
157 g_fserrno = 1;
158 spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL);
159 CU_ASSERT(g_fserrno == 0);
160 CU_ASSERT(TAILQ_EMPTY(&fs->files));
161
162 spdk_fs_unload(fs, fs_op_complete, NULL);
163 CU_ASSERT(g_fserrno == 0);
164
165 spdk_free_thread();
166}
167
168static void
169fs_truncate(void)
170{
171 struct spdk_filesystem *fs;
172 struct spdk_bs_dev dev;
173
174 init_dev(&dev);
175 spdk_allocate_thread();
176
177 spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
178 SPDK_CU_ASSERT_FATAL(g_fs != NULL);
179 CU_ASSERT(g_fserrno == 0);
180 fs = g_fs;
181
182 g_file = NULL;
183 g_fserrno = 1;
184 spdk_fs_open_file_async(fs, "file1", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL);
185 CU_ASSERT(g_fserrno == 0);
186 SPDK_CU_ASSERT_FATAL(g_file != NULL);
187
188 g_fserrno = 1;
189 spdk_file_truncate_async(g_file, 18 * 1024 * 1024 + 1, fs_op_complete, NULL);
190 CU_ASSERT(g_fserrno == 0);
191 CU_ASSERT(g_file->length == 18 * 1024 * 1024 + 1);
192
193 g_fserrno = 1;
194 spdk_file_truncate_async(g_file, 1, fs_op_complete, NULL);
195 CU_ASSERT(g_fserrno == 0);
196 CU_ASSERT(g_file->length == 1);
197
198 g_fserrno = 1;
199 spdk_file_truncate_async(g_file, 18 * 1024 * 1024 + 1, fs_op_complete, NULL);
200 CU_ASSERT(g_fserrno == 0);
201 CU_ASSERT(g_file->length == 18 * 1024 * 1024 + 1);
202
203 g_fserrno = 1;
204 spdk_file_close_async(g_file, fs_op_complete, NULL);
205 CU_ASSERT(g_fserrno == 0);
206 CU_ASSERT(g_file->ref_count == 0);
207
208 g_fserrno = 1;
209 spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL);
210 CU_ASSERT(g_fserrno == 0);
211 CU_ASSERT(TAILQ_EMPTY(&fs->files));
212
213 spdk_fs_unload(fs, fs_op_complete, NULL);
214 CU_ASSERT(g_fserrno == 0);
215
216 spdk_free_thread();
217}
218
219static void
220fs_rename(void)
221{
222 struct spdk_filesystem *fs;
223 struct spdk_file *file, *file2;
224 struct spdk_bs_dev dev;
225
226 init_dev(&dev);
227 spdk_allocate_thread();
228
229 spdk_fs_init(&dev, NULL, fs_op_with_handle_complete, NULL);
230 SPDK_CU_ASSERT_FATAL(g_fs != NULL);
231 CU_ASSERT(g_fserrno == 0);
232 fs = g_fs;
233
234 g_fserrno = 1;
235 spdk_fs_create_file_async(fs, "file1", create_cb, NULL);
236 CU_ASSERT(g_fserrno == 0);
237
238 g_file = NULL;
239 g_fserrno = 1;
240 spdk_fs_open_file_async(fs, "file1", 0, open_cb, NULL);
241 CU_ASSERT(g_fserrno == 0);
242 SPDK_CU_ASSERT_FATAL(g_file != NULL);
243 CU_ASSERT(g_file->ref_count == 1);
244
245 file = g_file;
246 g_file = NULL;
247 g_fserrno = 1;
248 spdk_file_close_async(file, fs_op_complete, NULL);
249 CU_ASSERT(g_fserrno == 0);
250 SPDK_CU_ASSERT_FATAL(file->ref_count == 0);
251
252 g_file = NULL;
253 g_fserrno = 1;
254 spdk_fs_open_file_async(fs, "file2", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL);
255 CU_ASSERT(g_fserrno == 0);
256 SPDK_CU_ASSERT_FATAL(g_file != NULL);
257 CU_ASSERT(g_file->ref_count == 1);
258
259 file2 = g_file;
260 g_file = NULL;
261 g_fserrno = 1;
262 spdk_file_close_async(file2, fs_op_complete, NULL);
263 CU_ASSERT(g_fserrno == 0);
264 SPDK_CU_ASSERT_FATAL(file2->ref_count == 0);
265
266 /*
267 * Do a 3-way rename. This should delete the old "file2", then rename
268 * "file1" to "file2".
269 */
270 g_fserrno = 1;
271 spdk_fs_rename_file_async(fs, "file1", "file2", fs_op_complete, NULL);
272 CU_ASSERT(g_fserrno == 0);
273 CU_ASSERT(file->ref_count == 0);
274 CU_ASSERT(!strcmp(file->name, "file2"));
275 CU_ASSERT(TAILQ_FIRST(&fs->files) == file);
276 CU_ASSERT(TAILQ_NEXT(file, tailq) == NULL);
277
278 g_fserrno = 0;
279 spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL);
280 CU_ASSERT(g_fserrno == -ENOENT);
281 CU_ASSERT(!TAILQ_EMPTY(&fs->files));
282
283 g_fserrno = 1;
284 spdk_fs_delete_file_async(fs, "file2", delete_cb, NULL);
285 CU_ASSERT(g_fserrno == 0);
286 CU_ASSERT(TAILQ_EMPTY(&fs->files));
287
288 spdk_fs_unload(fs, fs_op_complete, NULL);
289 CU_ASSERT(g_fserrno == 0);
290
291 spdk_free_thread();
292}
293
294static void
295tree_find_buffer_ut(void)
296{
297 struct cache_tree *root;
298 struct cache_tree *level1_0;
299 struct cache_tree *level0_0_0;
300 struct cache_tree *level0_0_12;
301 struct cache_buffer *leaf_0_0_4;
302 struct cache_buffer *leaf_0_12_8;
303 struct cache_buffer *leaf_9_23_15;
304 struct cache_buffer *buffer;
305
306 level1_0 = calloc(1, sizeof(struct cache_tree));
307 SPDK_CU_ASSERT_FATAL(level1_0 != NULL);
308 level0_0_0 = calloc(1, sizeof(struct cache_tree));
309 SPDK_CU_ASSERT_FATAL(level0_0_0 != NULL);
310 level0_0_12 = calloc(1, sizeof(struct cache_tree));
311 SPDK_CU_ASSERT_FATAL(level0_0_12 != NULL);
312 leaf_0_0_4 = calloc(1, sizeof(struct cache_buffer));
313 SPDK_CU_ASSERT_FATAL(leaf_0_0_4 != NULL);
314 leaf_0_12_8 = calloc(1, sizeof(struct cache_buffer));
315 SPDK_CU_ASSERT_FATAL(leaf_0_12_8 != NULL);
316 leaf_9_23_15 = calloc(1, sizeof(struct cache_buffer));
317 SPDK_CU_ASSERT_FATAL(leaf_9_23_15 != NULL);
318
319 level1_0->level = 1;
320 level0_0_0->level = 0;
321 level0_0_12->level = 0;
322
323 leaf_0_0_4->offset = CACHE_BUFFER_SIZE * 4;
324 level0_0_0->u.buffer[4] = leaf_0_0_4;
325 level0_0_0->present_mask |= (1ULL << 4);
326
327 leaf_0_12_8->offset = CACHE_TREE_LEVEL_SIZE(1) * 12 + CACHE_BUFFER_SIZE * 8;
328 level0_0_12->u.buffer[8] = leaf_0_12_8;
329 level0_0_12->present_mask |= (1ULL << 8);
330
331 level1_0->u.tree[0] = level0_0_0;
332 level1_0->present_mask |= (1ULL << 0);
333 level1_0->u.tree[12] = level0_0_12;
334 level1_0->present_mask |= (1ULL << 12);
335
336 buffer = spdk_tree_find_buffer(NULL, 0);
337 CU_ASSERT(buffer == NULL);
338
339 buffer = spdk_tree_find_buffer(level0_0_0, 0);
340 CU_ASSERT(buffer == NULL);
341
342 buffer = spdk_tree_find_buffer(level0_0_0, CACHE_TREE_LEVEL_SIZE(0) + 1);
343 CU_ASSERT(buffer == NULL);
344
345 buffer = spdk_tree_find_buffer(level0_0_0, leaf_0_0_4->offset);
346 CU_ASSERT(buffer == leaf_0_0_4);
347
348 buffer = spdk_tree_find_buffer(level1_0, leaf_0_0_4->offset);
349 CU_ASSERT(buffer == leaf_0_0_4);
350
351 buffer = spdk_tree_find_buffer(level1_0, leaf_0_12_8->offset);
352 CU_ASSERT(buffer == leaf_0_12_8);
353
354 buffer = spdk_tree_find_buffer(level1_0, leaf_0_12_8->offset + CACHE_BUFFER_SIZE - 1);
355 CU_ASSERT(buffer == leaf_0_12_8);
356
357 buffer = spdk_tree_find_buffer(level1_0, leaf_0_12_8->offset - 1);
358 CU_ASSERT(buffer == NULL);
359
360 leaf_9_23_15->offset = CACHE_TREE_LEVEL_SIZE(2) * 9 +
361 CACHE_TREE_LEVEL_SIZE(1) * 23 +
362 CACHE_BUFFER_SIZE * 15;
363 root = spdk_tree_insert_buffer(level1_0, leaf_9_23_15);
364 CU_ASSERT(root != level1_0);
365 buffer = spdk_tree_find_buffer(root, leaf_9_23_15->offset);
366 CU_ASSERT(buffer == leaf_9_23_15);
367 spdk_tree_free_buffers(root);
368 free(root);
369}
370
371int main(int argc, char **argv)
372{
373 CU_pSuite suite = NULL;
374 unsigned int num_failures;
375
376 if (CU_initialize_registry() != CUE_SUCCESS) {
377 return CU_get_error();
378 }
379
380 suite = CU_add_suite("blobfs", NULL, NULL);
381 if (suite == NULL) {
382 CU_cleanup_registry();
383 return CU_get_error();
384 }
385
386 if (
387 CU_add_test(suite, "fs_init", fs_init) == NULL ||
388 CU_add_test(suite, "fs_open", fs_open) == NULL ||
389 CU_add_test(suite, "fs_truncate", fs_truncate) == NULL ||
390 CU_add_test(suite, "fs_rename", fs_rename) == NULL ||
391 CU_add_test(suite, "tree_find_buffer", tree_find_buffer_ut) == NULL
392 ) {
393 CU_cleanup_registry();
394 return CU_get_error();
395 }
396
397 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
398 CU_basic_set_mode(CU_BRM_VERBOSE);
399 CU_basic_run_tests();
400 num_failures = CU_get_number_of_failures();
401 CU_cleanup_registry();
402 free(g_dev_buffer);
403 return num_failures;
404}