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