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