xref: /spdk/test/unit/lib/blobfs/blobfs_async_ut/blobfs_async_ut.c (revision ea941caeaf896fdf2aef7685f86f37023060faed)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2017 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/stdinc.h"
7 
8 #include "CUnit/Basic.h"
9 
10 #include "common/lib/ut_multithread.c"
11 
12 #include "spdk_internal/cunit.h"
13 #include "blobfs/blobfs.c"
14 #include "blobfs/tree.c"
15 #include "blob/blobstore.h"
16 
17 #include "unit/lib/blob/bs_dev_common.c"
18 
19 struct spdk_filesystem *g_fs;
20 struct spdk_file *g_file;
21 int g_fserrno;
22 
23 DEFINE_STUB(spdk_memory_domain_memzero, int, (struct spdk_memory_domain *src_domain,
24 		void *src_domain_ctx, struct iovec *iov, uint32_t iovcnt, void (*cpl_cb)(void *, int),
25 		void *cpl_cb_arg), 0);
26 DEFINE_STUB(spdk_mempool_lookup, struct spdk_mempool *, (const char *name), NULL);
27 
28 static void
fs_op_complete(void * ctx,int fserrno)29 fs_op_complete(void *ctx, int fserrno)
30 {
31 	g_fserrno = fserrno;
32 }
33 
34 static void
fs_op_with_handle_complete(void * ctx,struct spdk_filesystem * fs,int fserrno)35 fs_op_with_handle_complete(void *ctx, struct spdk_filesystem *fs, int fserrno)
36 {
37 	g_fs = fs;
38 	g_fserrno = fserrno;
39 }
40 
41 static void
fs_poll_threads(void)42 fs_poll_threads(void)
43 {
44 	poll_threads();
45 	while (spdk_thread_poll(g_cache_pool_thread, 0, 0) > 0) {}
46 }
47 
48 static void
fs_init(void)49 fs_init(void)
50 {
51 	struct spdk_filesystem *fs;
52 	struct spdk_bs_dev *dev;
53 
54 	dev = init_dev();
55 
56 	spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
57 	fs_poll_threads();
58 	SPDK_CU_ASSERT_FATAL(g_fs != NULL);
59 	CU_ASSERT(g_fserrno == 0);
60 	fs = g_fs;
61 	SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev);
62 
63 	g_fserrno = 1;
64 	spdk_fs_unload(fs, fs_op_complete, NULL);
65 	fs_poll_threads();
66 	CU_ASSERT(g_fserrno == 0);
67 }
68 
69 static void
create_cb(void * ctx,int fserrno)70 create_cb(void *ctx, int fserrno)
71 {
72 	g_fserrno = fserrno;
73 }
74 
75 static void
open_cb(void * ctx,struct spdk_file * f,int fserrno)76 open_cb(void *ctx, struct spdk_file *f, int fserrno)
77 {
78 	g_fserrno = fserrno;
79 	g_file = f;
80 }
81 
82 static void
delete_cb(void * ctx,int fserrno)83 delete_cb(void *ctx, int fserrno)
84 {
85 	g_fserrno = fserrno;
86 }
87 
88 static void
fs_open(void)89 fs_open(void)
90 {
91 	struct spdk_filesystem *fs;
92 	spdk_fs_iter iter;
93 	struct spdk_bs_dev *dev;
94 	struct spdk_file *file;
95 	char name[257] = {'\0'};
96 
97 	dev = init_dev();
98 	memset(name, 'a', sizeof(name) - 1);
99 
100 	spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
101 	fs_poll_threads();
102 	SPDK_CU_ASSERT_FATAL(g_fs != NULL);
103 	CU_ASSERT(g_fserrno == 0);
104 	fs = g_fs;
105 	SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev);
106 
107 	g_fserrno = 0;
108 	/* Open should fail, because the file name is too long. */
109 	spdk_fs_open_file_async(fs, name, SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL);
110 	fs_poll_threads();
111 	CU_ASSERT(g_fserrno == -ENAMETOOLONG);
112 
113 	g_fserrno = 0;
114 	spdk_fs_open_file_async(fs, "file1", 0, open_cb, NULL);
115 	fs_poll_threads();
116 	CU_ASSERT(g_fserrno == -ENOENT);
117 
118 	g_file = NULL;
119 	g_fserrno = 1;
120 	spdk_fs_open_file_async(fs, "file1", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL);
121 	fs_poll_threads();
122 	CU_ASSERT(g_fserrno == 0);
123 	SPDK_CU_ASSERT_FATAL(g_file != NULL);
124 	CU_ASSERT(!strcmp("file1", g_file->name));
125 	CU_ASSERT(g_file->ref_count == 1);
126 
127 	iter = spdk_fs_iter_first(fs);
128 	CU_ASSERT(iter != NULL);
129 	file = spdk_fs_iter_get_file(iter);
130 	SPDK_CU_ASSERT_FATAL(file != NULL);
131 	CU_ASSERT(!strcmp("file1", file->name));
132 	iter = spdk_fs_iter_next(iter);
133 	CU_ASSERT(iter == NULL);
134 
135 	g_fserrno = 0;
136 	/* Delete should successful, we will mark the file as deleted. */
137 	spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL);
138 	fs_poll_threads();
139 	CU_ASSERT(g_fserrno == 0);
140 	CU_ASSERT(!TAILQ_EMPTY(&fs->files));
141 
142 	g_fserrno = 1;
143 	spdk_file_close_async(g_file, fs_op_complete, NULL);
144 	fs_poll_threads();
145 	CU_ASSERT(g_fserrno == 0);
146 	CU_ASSERT(TAILQ_EMPTY(&fs->files));
147 
148 	g_fserrno = 1;
149 	spdk_fs_unload(fs, fs_op_complete, NULL);
150 	fs_poll_threads();
151 	CU_ASSERT(g_fserrno == 0);
152 }
153 
154 static void
fs_create(void)155 fs_create(void)
156 {
157 	struct spdk_filesystem *fs;
158 	struct spdk_bs_dev *dev;
159 	char name[257] = {'\0'};
160 
161 	dev = init_dev();
162 	memset(name, 'a', sizeof(name) - 1);
163 
164 	spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
165 	fs_poll_threads();
166 	SPDK_CU_ASSERT_FATAL(g_fs != NULL);
167 	CU_ASSERT(g_fserrno == 0);
168 	fs = g_fs;
169 	SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev);
170 
171 	g_fserrno = 0;
172 	/* Create should fail, because the file name is too long. */
173 	spdk_fs_create_file_async(fs, name, create_cb, NULL);
174 	fs_poll_threads();
175 	CU_ASSERT(g_fserrno == -ENAMETOOLONG);
176 
177 	g_fserrno = 1;
178 	spdk_fs_create_file_async(fs, "file1", create_cb, NULL);
179 	fs_poll_threads();
180 	CU_ASSERT(g_fserrno == 0);
181 
182 	g_fserrno = 1;
183 	spdk_fs_create_file_async(fs, "file1", create_cb, NULL);
184 	fs_poll_threads();
185 	CU_ASSERT(g_fserrno == -EEXIST);
186 
187 	g_fserrno = 1;
188 	spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL);
189 	fs_poll_threads();
190 	CU_ASSERT(g_fserrno == 0);
191 	CU_ASSERT(TAILQ_EMPTY(&fs->files));
192 
193 	g_fserrno = 1;
194 	spdk_fs_unload(fs, fs_op_complete, NULL);
195 	fs_poll_threads();
196 	CU_ASSERT(g_fserrno == 0);
197 }
198 
199 static void
fs_truncate(void)200 fs_truncate(void)
201 {
202 	struct spdk_filesystem *fs;
203 	struct spdk_bs_dev *dev;
204 
205 	dev = init_dev();
206 
207 	spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
208 	fs_poll_threads();
209 	SPDK_CU_ASSERT_FATAL(g_fs != NULL);
210 	CU_ASSERT(g_fserrno == 0);
211 	fs = g_fs;
212 	SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev);
213 
214 	g_file = NULL;
215 	g_fserrno = 1;
216 	spdk_fs_open_file_async(fs, "file1", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL);
217 	fs_poll_threads();
218 	CU_ASSERT(g_fserrno == 0);
219 	SPDK_CU_ASSERT_FATAL(g_file != NULL);
220 
221 	g_fserrno = 1;
222 	spdk_file_truncate_async(g_file, 18 * 1024 * 1024 + 1, fs_op_complete, NULL);
223 	fs_poll_threads();
224 	CU_ASSERT(g_fserrno == 0);
225 	CU_ASSERT(g_file->length == 18 * 1024 * 1024 + 1);
226 
227 	g_fserrno = 1;
228 	spdk_file_truncate_async(g_file, 1, fs_op_complete, NULL);
229 	fs_poll_threads();
230 	CU_ASSERT(g_fserrno == 0);
231 	CU_ASSERT(g_file->length == 1);
232 
233 	g_fserrno = 1;
234 	spdk_file_truncate_async(g_file, 18 * 1024 * 1024 + 1, fs_op_complete, NULL);
235 	fs_poll_threads();
236 	CU_ASSERT(g_fserrno == 0);
237 	CU_ASSERT(g_file->length == 18 * 1024 * 1024 + 1);
238 
239 	g_fserrno = 1;
240 	spdk_file_close_async(g_file, fs_op_complete, NULL);
241 	fs_poll_threads();
242 	CU_ASSERT(g_fserrno == 0);
243 	CU_ASSERT(g_file->ref_count == 0);
244 
245 	g_fserrno = 1;
246 	spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL);
247 	fs_poll_threads();
248 	CU_ASSERT(g_fserrno == 0);
249 	CU_ASSERT(TAILQ_EMPTY(&fs->files));
250 
251 	g_fserrno = 1;
252 	spdk_fs_unload(fs, fs_op_complete, NULL);
253 	fs_poll_threads();
254 	CU_ASSERT(g_fserrno == 0);
255 }
256 
257 static void
fs_rename(void)258 fs_rename(void)
259 {
260 	struct spdk_filesystem *fs;
261 	struct spdk_file *file, *file2, *file_iter;
262 	struct spdk_bs_dev *dev;
263 
264 	dev = init_dev();
265 
266 	spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
267 	fs_poll_threads();
268 	SPDK_CU_ASSERT_FATAL(g_fs != NULL);
269 	CU_ASSERT(g_fserrno == 0);
270 	fs = g_fs;
271 	SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev);
272 
273 	g_fserrno = 1;
274 	spdk_fs_create_file_async(fs, "file1", create_cb, NULL);
275 	fs_poll_threads();
276 	CU_ASSERT(g_fserrno == 0);
277 
278 	g_file = NULL;
279 	g_fserrno = 1;
280 	spdk_fs_open_file_async(fs, "file1", 0, open_cb, NULL);
281 	fs_poll_threads();
282 	CU_ASSERT(g_fserrno == 0);
283 	SPDK_CU_ASSERT_FATAL(g_file != NULL);
284 	CU_ASSERT(g_file->ref_count == 1);
285 
286 	file = g_file;
287 	g_file = NULL;
288 	g_fserrno = 1;
289 	spdk_file_close_async(file, fs_op_complete, NULL);
290 	fs_poll_threads();
291 	CU_ASSERT(g_fserrno == 0);
292 	SPDK_CU_ASSERT_FATAL(file->ref_count == 0);
293 
294 	g_file = NULL;
295 	g_fserrno = 1;
296 	spdk_fs_open_file_async(fs, "file2", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL);
297 	fs_poll_threads();
298 	CU_ASSERT(g_fserrno == 0);
299 	SPDK_CU_ASSERT_FATAL(g_file != NULL);
300 	CU_ASSERT(g_file->ref_count == 1);
301 
302 	file2 = g_file;
303 	g_file = NULL;
304 	g_fserrno = 1;
305 	spdk_file_close_async(file2, fs_op_complete, NULL);
306 	fs_poll_threads();
307 	CU_ASSERT(g_fserrno == 0);
308 	SPDK_CU_ASSERT_FATAL(file2->ref_count == 0);
309 
310 	/*
311 	 * Do a 3-way rename.  This should delete the old "file2", then rename
312 	 *  "file1" to "file2".
313 	 */
314 	g_fserrno = 1;
315 	spdk_fs_rename_file_async(fs, "file1", "file2", fs_op_complete, NULL);
316 	fs_poll_threads();
317 	CU_ASSERT(g_fserrno == 0);
318 	CU_ASSERT(file->ref_count == 0);
319 	CU_ASSERT(!strcmp(file->name, "file2"));
320 	CU_ASSERT(TAILQ_FIRST(&fs->files) == file);
321 	CU_ASSERT(TAILQ_NEXT(file, tailq) == NULL);
322 
323 	g_fserrno = 0;
324 	spdk_fs_delete_file_async(fs, "file1", delete_cb, NULL);
325 	fs_poll_threads();
326 	CU_ASSERT(g_fserrno == -ENOENT);
327 	CU_ASSERT(!TAILQ_EMPTY(&fs->files));
328 	TAILQ_FOREACH(file_iter, &fs->files, tailq) {
329 		if (file_iter == NULL) {
330 			SPDK_CU_ASSERT_FATAL(false);
331 		}
332 	}
333 
334 	g_fserrno = 1;
335 	spdk_fs_delete_file_async(fs, "file2", delete_cb, NULL);
336 	fs_poll_threads();
337 	CU_ASSERT(g_fserrno == 0);
338 	CU_ASSERT(TAILQ_EMPTY(&fs->files));
339 
340 	g_fserrno = 1;
341 	spdk_fs_unload(fs, fs_op_complete, NULL);
342 	fs_poll_threads();
343 	CU_ASSERT(g_fserrno == 0);
344 }
345 
346 static void
fs_rw_async(void)347 fs_rw_async(void)
348 {
349 	struct spdk_filesystem *fs;
350 	struct spdk_bs_dev *dev;
351 	uint8_t w_buf[4096];
352 	uint8_t r_buf[4096];
353 
354 	dev = init_dev();
355 
356 	spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
357 	fs_poll_threads();
358 	SPDK_CU_ASSERT_FATAL(g_fs != NULL);
359 	CU_ASSERT(g_fserrno == 0);
360 	fs = g_fs;
361 	SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev);
362 
363 	g_file = NULL;
364 	g_fserrno = 1;
365 	spdk_fs_open_file_async(fs, "file1", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL);
366 	fs_poll_threads();
367 	CU_ASSERT(g_fserrno == 0);
368 	SPDK_CU_ASSERT_FATAL(g_file != NULL);
369 
370 	/* Write file */
371 	CU_ASSERT(g_file->length == 0);
372 	g_fserrno = 1;
373 	memset(w_buf, 0x5a, sizeof(w_buf));
374 	spdk_file_write_async(g_file, fs->sync_target.sync_io_channel, w_buf, 0, 4096,
375 			      fs_op_complete, NULL);
376 	fs_poll_threads();
377 	CU_ASSERT(g_fserrno == 0);
378 	CU_ASSERT(g_file->length == 4096);
379 
380 	/* Read file */
381 	g_fserrno = 1;
382 	memset(r_buf, 0x0, sizeof(r_buf));
383 	spdk_file_read_async(g_file, fs->sync_target.sync_io_channel, r_buf, 0, 4096,
384 			     fs_op_complete, NULL);
385 	fs_poll_threads();
386 	CU_ASSERT(g_fserrno == 0);
387 	CU_ASSERT(memcmp(r_buf, w_buf, sizeof(r_buf)) == 0);
388 
389 	g_fserrno = 1;
390 	spdk_file_close_async(g_file, fs_op_complete, NULL);
391 	fs_poll_threads();
392 	CU_ASSERT(g_fserrno == 0);
393 
394 	g_fserrno = 1;
395 	spdk_fs_unload(fs, fs_op_complete, NULL);
396 	fs_poll_threads();
397 	CU_ASSERT(g_fserrno == 0);
398 }
399 
400 static void
fs_writev_readv_async(void)401 fs_writev_readv_async(void)
402 {
403 	struct spdk_filesystem *fs;
404 	struct spdk_bs_dev *dev;
405 	struct iovec w_iov[2];
406 	struct iovec r_iov[2];
407 	uint8_t w_buf[4096];
408 	uint8_t r_buf[4096];
409 
410 	dev = init_dev();
411 
412 	spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
413 	fs_poll_threads();
414 	SPDK_CU_ASSERT_FATAL(g_fs != NULL);
415 	CU_ASSERT(g_fserrno == 0);
416 	fs = g_fs;
417 	SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev);
418 
419 	g_file = NULL;
420 	g_fserrno = 1;
421 	spdk_fs_open_file_async(fs, "file1", SPDK_BLOBFS_OPEN_CREATE, open_cb, NULL);
422 	fs_poll_threads();
423 	CU_ASSERT(g_fserrno == 0);
424 	SPDK_CU_ASSERT_FATAL(g_file != NULL);
425 
426 	/* Write file */
427 	CU_ASSERT(g_file->length == 0);
428 	g_fserrno = 1;
429 	memset(w_buf, 0x5a, sizeof(w_buf));
430 	w_iov[0].iov_base = w_buf;
431 	w_iov[0].iov_len = 2048;
432 	w_iov[1].iov_base = w_buf + 2048;
433 	w_iov[1].iov_len = 2048;
434 	spdk_file_writev_async(g_file, fs->sync_target.sync_io_channel,
435 			       w_iov, 2, 0, 4096, fs_op_complete, NULL);
436 	fs_poll_threads();
437 	CU_ASSERT(g_fserrno == 0);
438 	CU_ASSERT(g_file->length == 4096);
439 
440 	/* Read file */
441 	g_fserrno = 1;
442 	memset(r_buf, 0x0, sizeof(r_buf));
443 	r_iov[0].iov_base = r_buf;
444 	r_iov[0].iov_len = 2048;
445 	r_iov[1].iov_base = r_buf + 2048;
446 	r_iov[1].iov_len = 2048;
447 	spdk_file_readv_async(g_file, fs->sync_target.sync_io_channel,
448 			      r_iov, 2, 0, 4096, fs_op_complete, NULL);
449 	fs_poll_threads();
450 	CU_ASSERT(g_fserrno == 0);
451 	CU_ASSERT(memcmp(r_buf, w_buf, sizeof(r_buf)) == 0);
452 
453 	/* Overwrite file with block aligned */
454 	g_fserrno = 1;
455 	memset(w_buf, 0x6a, sizeof(w_buf));
456 	w_iov[0].iov_base = w_buf;
457 	w_iov[0].iov_len = 2048;
458 	w_iov[1].iov_base = w_buf + 2048;
459 	w_iov[1].iov_len = 2048;
460 	spdk_file_writev_async(g_file, fs->sync_target.sync_io_channel,
461 			       w_iov, 2, 0, 4096, fs_op_complete, NULL);
462 	fs_poll_threads();
463 	CU_ASSERT(g_fserrno == 0);
464 	CU_ASSERT(g_file->length == 4096);
465 
466 	/* Read file to verify the overwritten data */
467 	g_fserrno = 1;
468 	memset(r_buf, 0x0, sizeof(r_buf));
469 	r_iov[0].iov_base = r_buf;
470 	r_iov[0].iov_len = 2048;
471 	r_iov[1].iov_base = r_buf + 2048;
472 	r_iov[1].iov_len = 2048;
473 	spdk_file_readv_async(g_file, fs->sync_target.sync_io_channel,
474 			      r_iov, 2, 0, 4096, fs_op_complete, NULL);
475 	fs_poll_threads();
476 	CU_ASSERT(g_fserrno == 0);
477 	CU_ASSERT(memcmp(r_buf, w_buf, sizeof(r_buf)) == 0);
478 
479 	g_fserrno = 1;
480 	spdk_file_close_async(g_file, fs_op_complete, NULL);
481 	fs_poll_threads();
482 	CU_ASSERT(g_fserrno == 0);
483 
484 	g_fserrno = 1;
485 	spdk_fs_unload(fs, fs_op_complete, NULL);
486 	fs_poll_threads();
487 	CU_ASSERT(g_fserrno == 0);
488 }
489 
490 static void
tree_find_buffer_ut(void)491 tree_find_buffer_ut(void)
492 {
493 	struct cache_tree *root;
494 	struct cache_tree *level1_0;
495 	struct cache_tree *level0_0_0;
496 	struct cache_tree *level0_0_12;
497 	struct cache_buffer *leaf_0_0_4;
498 	struct cache_buffer *leaf_0_12_8;
499 	struct cache_buffer *leaf_9_23_15;
500 	struct cache_buffer *buffer;
501 
502 	level1_0 = calloc(1, sizeof(struct cache_tree));
503 	SPDK_CU_ASSERT_FATAL(level1_0 != NULL);
504 	level0_0_0 = calloc(1, sizeof(struct cache_tree));
505 	SPDK_CU_ASSERT_FATAL(level0_0_0 != NULL);
506 	level0_0_12 = calloc(1, sizeof(struct cache_tree));
507 	SPDK_CU_ASSERT_FATAL(level0_0_12 != NULL);
508 	leaf_0_0_4 = calloc(1, sizeof(struct cache_buffer));
509 	SPDK_CU_ASSERT_FATAL(leaf_0_0_4 != NULL);
510 	leaf_0_12_8 = calloc(1, sizeof(struct cache_buffer));
511 	SPDK_CU_ASSERT_FATAL(leaf_0_12_8 != NULL);
512 	leaf_9_23_15 = calloc(1, sizeof(struct cache_buffer));
513 	SPDK_CU_ASSERT_FATAL(leaf_9_23_15 != NULL);
514 
515 	level1_0->level = 1;
516 	level0_0_0->level = 0;
517 	level0_0_12->level = 0;
518 
519 	leaf_0_0_4->offset = CACHE_BUFFER_SIZE * 4;
520 	level0_0_0->u.buffer[4] = leaf_0_0_4;
521 	level0_0_0->present_mask |= (1ULL << 4);
522 
523 	leaf_0_12_8->offset = CACHE_TREE_LEVEL_SIZE(1) * 12 + CACHE_BUFFER_SIZE * 8;
524 	level0_0_12->u.buffer[8] = leaf_0_12_8;
525 	level0_0_12->present_mask |= (1ULL << 8);
526 
527 	level1_0->u.tree[0] = level0_0_0;
528 	level1_0->present_mask |= (1ULL << 0);
529 	level1_0->u.tree[12] = level0_0_12;
530 	level1_0->present_mask |= (1ULL << 12);
531 
532 	buffer = tree_find_buffer(NULL, 0);
533 	CU_ASSERT(buffer == NULL);
534 
535 	buffer = tree_find_buffer(level0_0_0, 0);
536 	CU_ASSERT(buffer == NULL);
537 
538 	buffer = tree_find_buffer(level0_0_0, CACHE_TREE_LEVEL_SIZE(0) + 1);
539 	CU_ASSERT(buffer == NULL);
540 
541 	buffer = tree_find_buffer(level0_0_0, leaf_0_0_4->offset);
542 	CU_ASSERT(buffer == leaf_0_0_4);
543 
544 	buffer = tree_find_buffer(level1_0, leaf_0_0_4->offset);
545 	CU_ASSERT(buffer == leaf_0_0_4);
546 
547 	buffer = tree_find_buffer(level1_0, leaf_0_12_8->offset);
548 	CU_ASSERT(buffer == leaf_0_12_8);
549 
550 	buffer = tree_find_buffer(level1_0, leaf_0_12_8->offset + CACHE_BUFFER_SIZE - 1);
551 	CU_ASSERT(buffer == leaf_0_12_8);
552 
553 	buffer = tree_find_buffer(level1_0, leaf_0_12_8->offset - 1);
554 	CU_ASSERT(buffer == NULL);
555 
556 	leaf_9_23_15->offset = CACHE_TREE_LEVEL_SIZE(2) * 9 +
557 			       CACHE_TREE_LEVEL_SIZE(1) * 23 +
558 			       CACHE_BUFFER_SIZE * 15;
559 	root = tree_insert_buffer(level1_0, leaf_9_23_15);
560 	CU_ASSERT(root != level1_0);
561 	buffer = tree_find_buffer(root, leaf_9_23_15->offset);
562 	CU_ASSERT(buffer == leaf_9_23_15);
563 	tree_free_buffers(root);
564 	free(root);
565 }
566 
567 static void
channel_ops(void)568 channel_ops(void)
569 {
570 	struct spdk_filesystem *fs;
571 	struct spdk_bs_dev *dev;
572 	struct spdk_io_channel *channel;
573 
574 	dev = init_dev();
575 
576 	spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
577 	fs_poll_threads();
578 	SPDK_CU_ASSERT_FATAL(g_fs != NULL);
579 	CU_ASSERT(g_fserrno == 0);
580 	fs = g_fs;
581 	SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev);
582 
583 	channel =  spdk_fs_alloc_io_channel(fs);
584 	CU_ASSERT(channel != NULL);
585 
586 	spdk_fs_free_io_channel(channel);
587 
588 	g_fserrno = 1;
589 	spdk_fs_unload(fs, fs_op_complete, NULL);
590 	fs_poll_threads();
591 	CU_ASSERT(g_fserrno == 0);
592 	g_fs = NULL;
593 }
594 
595 static void
channel_ops_sync(void)596 channel_ops_sync(void)
597 {
598 	struct spdk_filesystem *fs;
599 	struct spdk_bs_dev *dev;
600 	struct spdk_fs_thread_ctx *channel;
601 
602 	dev = init_dev();
603 
604 	spdk_fs_init(dev, NULL, NULL, fs_op_with_handle_complete, NULL);
605 	fs_poll_threads();
606 	SPDK_CU_ASSERT_FATAL(g_fs != NULL);
607 	CU_ASSERT(g_fserrno == 0);
608 	fs = g_fs;
609 	SPDK_CU_ASSERT_FATAL(fs->bs->dev == dev);
610 
611 	channel =  spdk_fs_alloc_thread_ctx(fs);
612 	CU_ASSERT(channel != NULL);
613 
614 	spdk_fs_free_thread_ctx(channel);
615 
616 	g_fserrno = 1;
617 	spdk_fs_unload(fs, fs_op_complete, NULL);
618 	fs_poll_threads();
619 	CU_ASSERT(g_fserrno == 0);
620 	g_fs = NULL;
621 }
622 
623 int
main(int argc,char ** argv)624 main(int argc, char **argv)
625 {
626 	CU_pSuite	suite = NULL;
627 	unsigned int	num_failures;
628 
629 	CU_initialize_registry();
630 
631 	suite = CU_add_suite("blobfs_async_ut", NULL, NULL);
632 
633 	CU_ADD_TEST(suite, fs_init);
634 	CU_ADD_TEST(suite, fs_open);
635 	CU_ADD_TEST(suite, fs_create);
636 	CU_ADD_TEST(suite, fs_truncate);
637 	CU_ADD_TEST(suite, fs_rename);
638 	CU_ADD_TEST(suite, fs_rw_async);
639 	CU_ADD_TEST(suite, fs_writev_readv_async);
640 	CU_ADD_TEST(suite, tree_find_buffer_ut);
641 	CU_ADD_TEST(suite, channel_ops);
642 	CU_ADD_TEST(suite, channel_ops_sync);
643 
644 	allocate_threads(1);
645 	set_thread(0);
646 
647 	g_dev_buffer = calloc(1, DEV_BUFFER_SIZE);
648 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
649 	CU_cleanup_registry();
650 	free(g_dev_buffer);
651 
652 	free_threads();
653 
654 	return num_failures;
655 }
656