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