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