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