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