1[cases.test_dirs_root] 2code = ''' 3 lfs_t lfs; 4 lfs_format(&lfs, cfg) => 0; 5 lfs_mount(&lfs, cfg) => 0; 6 lfs_dir_t dir; 7 lfs_dir_open(&lfs, &dir, "/") => 0; 8 struct lfs_info info; 9 lfs_dir_read(&lfs, &dir, &info) => 1; 10 assert(info.type == LFS_TYPE_DIR); 11 assert(strcmp(info.name, ".") == 0); 12 lfs_dir_read(&lfs, &dir, &info) => 1; 13 assert(info.type == LFS_TYPE_DIR); 14 assert(strcmp(info.name, "..") == 0); 15 lfs_dir_read(&lfs, &dir, &info) => 0; 16 lfs_dir_close(&lfs, &dir) => 0; 17 lfs_unmount(&lfs) => 0; 18''' 19 20[cases.test_dirs_many_creation] 21defines.N = 'range(3, 100, 3)' 22if = 'N < BLOCK_COUNT/2' 23code = ''' 24 lfs_t lfs; 25 lfs_format(&lfs, cfg) => 0; 26 27 lfs_mount(&lfs, cfg) => 0; 28 for (int i = 0; i < N; i++) { 29 char path[1024]; 30 sprintf(path, "dir%03d", i); 31 lfs_mkdir(&lfs, path) => 0; 32 } 33 lfs_unmount(&lfs) => 0; 34 35 lfs_mount(&lfs, cfg) => 0; 36 lfs_dir_t dir; 37 lfs_dir_open(&lfs, &dir, "/") => 0; 38 struct lfs_info info; 39 lfs_dir_read(&lfs, &dir, &info) => 1; 40 assert(info.type == LFS_TYPE_DIR); 41 assert(strcmp(info.name, ".") == 0); 42 lfs_dir_read(&lfs, &dir, &info) => 1; 43 assert(info.type == LFS_TYPE_DIR); 44 assert(strcmp(info.name, "..") == 0); 45 for (int i = 0; i < N; i++) { 46 char path[1024]; 47 sprintf(path, "dir%03d", i); 48 lfs_dir_read(&lfs, &dir, &info) => 1; 49 assert(info.type == LFS_TYPE_DIR); 50 assert(strcmp(info.name, path) == 0); 51 } 52 lfs_dir_read(&lfs, &dir, &info) => 0; 53 lfs_dir_close(&lfs, &dir) => 0; 54 lfs_unmount(&lfs) => 0; 55''' 56 57[cases.test_dirs_many_removal] 58defines.N = 'range(3, 100, 11)' 59if = 'N < BLOCK_COUNT/2' 60code = ''' 61 lfs_t lfs; 62 lfs_format(&lfs, cfg) => 0; 63 64 lfs_mount(&lfs, cfg) => 0; 65 for (int i = 0; i < N; i++) { 66 char path[1024]; 67 sprintf(path, "removeme%03d", i); 68 lfs_mkdir(&lfs, path) => 0; 69 } 70 lfs_unmount(&lfs) => 0; 71 72 lfs_mount(&lfs, cfg) => 0; 73 lfs_dir_t dir; 74 lfs_dir_open(&lfs, &dir, "/") => 0; 75 struct lfs_info info; 76 lfs_dir_read(&lfs, &dir, &info) => 1; 77 assert(info.type == LFS_TYPE_DIR); 78 assert(strcmp(info.name, ".") == 0); 79 lfs_dir_read(&lfs, &dir, &info) => 1; 80 assert(info.type == LFS_TYPE_DIR); 81 assert(strcmp(info.name, "..") == 0); 82 for (int i = 0; i < N; i++) { 83 char path[1024]; 84 sprintf(path, "removeme%03d", i); 85 lfs_dir_read(&lfs, &dir, &info) => 1; 86 assert(info.type == LFS_TYPE_DIR); 87 assert(strcmp(info.name, path) == 0); 88 } 89 lfs_dir_read(&lfs, &dir, &info) => 0; 90 lfs_dir_close(&lfs, &dir) => 0; 91 lfs_unmount(&lfs); 92 93 lfs_mount(&lfs, cfg) => 0; 94 for (int i = 0; i < N; i++) { 95 char path[1024]; 96 sprintf(path, "removeme%03d", i); 97 lfs_remove(&lfs, path) => 0; 98 } 99 lfs_unmount(&lfs); 100 101 lfs_mount(&lfs, cfg) => 0; 102 lfs_dir_open(&lfs, &dir, "/") => 0; 103 lfs_dir_read(&lfs, &dir, &info) => 1; 104 assert(info.type == LFS_TYPE_DIR); 105 assert(strcmp(info.name, ".") == 0); 106 lfs_dir_read(&lfs, &dir, &info) => 1; 107 assert(info.type == LFS_TYPE_DIR); 108 assert(strcmp(info.name, "..") == 0); 109 lfs_dir_read(&lfs, &dir, &info) => 0; 110 lfs_dir_close(&lfs, &dir) => 0; 111 lfs_unmount(&lfs) => 0; 112''' 113 114[cases.test_dirs_many_rename] 115defines.N = 'range(3, 100, 11)' 116if = 'N < BLOCK_COUNT/2' 117code = ''' 118 lfs_t lfs; 119 lfs_format(&lfs, cfg) => 0; 120 121 lfs_mount(&lfs, cfg) => 0; 122 for (int i = 0; i < N; i++) { 123 char path[1024]; 124 sprintf(path, "test%03d", i); 125 lfs_mkdir(&lfs, path) => 0; 126 } 127 lfs_unmount(&lfs) => 0; 128 129 lfs_mount(&lfs, cfg) => 0; 130 lfs_dir_t dir; 131 lfs_dir_open(&lfs, &dir, "/") => 0; 132 struct lfs_info info; 133 lfs_dir_read(&lfs, &dir, &info) => 1; 134 assert(info.type == LFS_TYPE_DIR); 135 assert(strcmp(info.name, ".") == 0); 136 lfs_dir_read(&lfs, &dir, &info) => 1; 137 assert(info.type == LFS_TYPE_DIR); 138 assert(strcmp(info.name, "..") == 0); 139 for (int i = 0; i < N; i++) { 140 char path[1024]; 141 sprintf(path, "test%03d", i); 142 lfs_dir_read(&lfs, &dir, &info) => 1; 143 assert(info.type == LFS_TYPE_DIR); 144 assert(strcmp(info.name, path) == 0); 145 } 146 lfs_dir_read(&lfs, &dir, &info) => 0; 147 lfs_dir_close(&lfs, &dir) => 0; 148 lfs_unmount(&lfs); 149 150 lfs_mount(&lfs, cfg) => 0; 151 for (int i = 0; i < N; i++) { 152 char oldpath[128]; 153 char newpath[128]; 154 sprintf(oldpath, "test%03d", i); 155 sprintf(newpath, "tedd%03d", i); 156 lfs_rename(&lfs, oldpath, newpath) => 0; 157 } 158 lfs_unmount(&lfs); 159 160 lfs_mount(&lfs, cfg) => 0; 161 lfs_dir_open(&lfs, &dir, "/") => 0; 162 lfs_dir_read(&lfs, &dir, &info) => 1; 163 assert(info.type == LFS_TYPE_DIR); 164 assert(strcmp(info.name, ".") == 0); 165 lfs_dir_read(&lfs, &dir, &info) => 1; 166 assert(info.type == LFS_TYPE_DIR); 167 assert(strcmp(info.name, "..") == 0); 168 for (int i = 0; i < N; i++) { 169 char path[1024]; 170 sprintf(path, "tedd%03d", i); 171 lfs_dir_read(&lfs, &dir, &info) => 1; 172 assert(info.type == LFS_TYPE_DIR); 173 assert(strcmp(info.name, path) == 0); 174 } 175 lfs_dir_read(&lfs, &dir, &info) => 0; 176 lfs_dir_close(&lfs, &dir) => 0; 177 lfs_unmount(&lfs); 178''' 179 180[cases.test_dirs_many_reentrant] 181defines.N = [5, 11] 182if = 'BLOCK_COUNT >= 4*N' 183reentrant = true 184code = ''' 185 lfs_t lfs; 186 int err = lfs_mount(&lfs, cfg); 187 if (err) { 188 lfs_format(&lfs, cfg) => 0; 189 lfs_mount(&lfs, cfg) => 0; 190 } 191 192 for (int i = 0; i < N; i++) { 193 char path[1024]; 194 sprintf(path, "hi%03d", i); 195 err = lfs_mkdir(&lfs, path); 196 assert(err == 0 || err == LFS_ERR_EXIST); 197 } 198 199 for (int i = 0; i < N; i++) { 200 char path[1024]; 201 sprintf(path, "hello%03d", i); 202 err = lfs_remove(&lfs, path); 203 assert(err == 0 || err == LFS_ERR_NOENT); 204 } 205 206 lfs_dir_t dir; 207 lfs_dir_open(&lfs, &dir, "/") => 0; 208 struct lfs_info info; 209 lfs_dir_read(&lfs, &dir, &info) => 1; 210 assert(info.type == LFS_TYPE_DIR); 211 assert(strcmp(info.name, ".") == 0); 212 lfs_dir_read(&lfs, &dir, &info) => 1; 213 assert(info.type == LFS_TYPE_DIR); 214 assert(strcmp(info.name, "..") == 0); 215 for (int i = 0; i < N; i++) { 216 char path[1024]; 217 sprintf(path, "hi%03d", i); 218 lfs_dir_read(&lfs, &dir, &info) => 1; 219 assert(info.type == LFS_TYPE_DIR); 220 assert(strcmp(info.name, path) == 0); 221 } 222 lfs_dir_read(&lfs, &dir, &info) => 0; 223 lfs_dir_close(&lfs, &dir) => 0; 224 225 for (int i = 0; i < N; i++) { 226 char oldpath[128]; 227 char newpath[128]; 228 sprintf(oldpath, "hi%03d", i); 229 sprintf(newpath, "hello%03d", i); 230 // YES this can overwrite an existing newpath 231 lfs_rename(&lfs, oldpath, newpath) => 0; 232 } 233 234 lfs_dir_open(&lfs, &dir, "/") => 0; 235 lfs_dir_read(&lfs, &dir, &info) => 1; 236 assert(info.type == LFS_TYPE_DIR); 237 assert(strcmp(info.name, ".") == 0); 238 lfs_dir_read(&lfs, &dir, &info) => 1; 239 assert(info.type == LFS_TYPE_DIR); 240 assert(strcmp(info.name, "..") == 0); 241 for (int i = 0; i < N; i++) { 242 char path[1024]; 243 sprintf(path, "hello%03d", i); 244 lfs_dir_read(&lfs, &dir, &info) => 1; 245 assert(info.type == LFS_TYPE_DIR); 246 assert(strcmp(info.name, path) == 0); 247 } 248 lfs_dir_read(&lfs, &dir, &info) => 0; 249 lfs_dir_close(&lfs, &dir) => 0; 250 251 for (int i = 0; i < N; i++) { 252 char path[1024]; 253 sprintf(path, "hello%03d", i); 254 lfs_remove(&lfs, path) => 0; 255 } 256 257 lfs_dir_open(&lfs, &dir, "/") => 0; 258 lfs_dir_read(&lfs, &dir, &info) => 1; 259 assert(info.type == LFS_TYPE_DIR); 260 assert(strcmp(info.name, ".") == 0); 261 lfs_dir_read(&lfs, &dir, &info) => 1; 262 assert(info.type == LFS_TYPE_DIR); 263 assert(strcmp(info.name, "..") == 0); 264 lfs_dir_read(&lfs, &dir, &info) => 0; 265 lfs_dir_close(&lfs, &dir) => 0; 266 lfs_unmount(&lfs) => 0; 267''' 268 269[cases.test_dirs_file_creation] 270defines.N = 'range(3, 100, 11)' 271if = 'N < BLOCK_COUNT/2' 272code = ''' 273 lfs_t lfs; 274 lfs_format(&lfs, cfg) => 0; 275 276 lfs_mount(&lfs, cfg) => 0; 277 for (int i = 0; i < N; i++) { 278 char path[1024]; 279 sprintf(path, "file%03d", i); 280 lfs_file_t file; 281 lfs_file_open(&lfs, &file, path, 282 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; 283 lfs_file_close(&lfs, &file) => 0; 284 } 285 lfs_unmount(&lfs) => 0; 286 287 lfs_mount(&lfs, cfg) => 0; 288 lfs_dir_t dir; 289 lfs_dir_open(&lfs, &dir, "/") => 0; 290 struct lfs_info info; 291 lfs_dir_read(&lfs, &dir, &info) => 1; 292 assert(info.type == LFS_TYPE_DIR); 293 assert(strcmp(info.name, ".") == 0); 294 lfs_dir_read(&lfs, &dir, &info) => 1; 295 assert(info.type == LFS_TYPE_DIR); 296 assert(strcmp(info.name, "..") == 0); 297 for (int i = 0; i < N; i++) { 298 char path[1024]; 299 sprintf(path, "file%03d", i); 300 lfs_dir_read(&lfs, &dir, &info) => 1; 301 assert(info.type == LFS_TYPE_REG); 302 assert(strcmp(info.name, path) == 0); 303 } 304 lfs_dir_read(&lfs, &dir, &info) => 0; 305 lfs_dir_close(&lfs, &dir) => 0; 306 lfs_unmount(&lfs); 307''' 308 309[cases.test_dirs_file_removal] 310defines.N = 'range(3, 100, 11)' 311if = 'N < BLOCK_COUNT/2' 312code = ''' 313 lfs_t lfs; 314 lfs_format(&lfs, cfg) => 0; 315 316 lfs_mount(&lfs, cfg) => 0; 317 for (int i = 0; i < N; i++) { 318 char path[1024]; 319 sprintf(path, "removeme%03d", i); 320 lfs_file_t file; 321 lfs_file_open(&lfs, &file, path, 322 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; 323 lfs_file_close(&lfs, &file) => 0; 324 } 325 lfs_unmount(&lfs) => 0; 326 327 lfs_mount(&lfs, cfg) => 0; 328 lfs_dir_t dir; 329 lfs_dir_open(&lfs, &dir, "/") => 0; 330 struct lfs_info info; 331 lfs_dir_read(&lfs, &dir, &info) => 1; 332 assert(info.type == LFS_TYPE_DIR); 333 assert(strcmp(info.name, ".") == 0); 334 lfs_dir_read(&lfs, &dir, &info) => 1; 335 assert(info.type == LFS_TYPE_DIR); 336 assert(strcmp(info.name, "..") == 0); 337 for (int i = 0; i < N; i++) { 338 char path[1024]; 339 sprintf(path, "removeme%03d", i); 340 lfs_dir_read(&lfs, &dir, &info) => 1; 341 assert(info.type == LFS_TYPE_REG); 342 assert(strcmp(info.name, path) == 0); 343 } 344 lfs_dir_read(&lfs, &dir, &info) => 0; 345 lfs_dir_close(&lfs, &dir) => 0; 346 lfs_unmount(&lfs); 347 348 lfs_mount(&lfs, cfg) => 0; 349 for (int i = 0; i < N; i++) { 350 char path[1024]; 351 sprintf(path, "removeme%03d", i); 352 lfs_remove(&lfs, path) => 0; 353 } 354 lfs_unmount(&lfs); 355 356 lfs_mount(&lfs, cfg) => 0; 357 lfs_dir_open(&lfs, &dir, "/") => 0; 358 lfs_dir_read(&lfs, &dir, &info) => 1; 359 assert(info.type == LFS_TYPE_DIR); 360 assert(strcmp(info.name, ".") == 0); 361 lfs_dir_read(&lfs, &dir, &info) => 1; 362 assert(info.type == LFS_TYPE_DIR); 363 assert(strcmp(info.name, "..") == 0); 364 lfs_dir_read(&lfs, &dir, &info) => 0; 365 lfs_dir_close(&lfs, &dir) => 0; 366 lfs_unmount(&lfs) => 0; 367''' 368 369[cases.test_dirs_file_rename] 370defines.N = 'range(3, 100, 11)' 371if = 'N < BLOCK_COUNT/2' 372code = ''' 373 lfs_t lfs; 374 lfs_format(&lfs, cfg) => 0; 375 376 lfs_mount(&lfs, cfg) => 0; 377 for (int i = 0; i < N; i++) { 378 char path[1024]; 379 sprintf(path, "test%03d", i); 380 lfs_file_t file; 381 lfs_file_open(&lfs, &file, path, 382 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; 383 lfs_file_close(&lfs, &file) => 0; 384 } 385 lfs_unmount(&lfs) => 0; 386 387 lfs_mount(&lfs, cfg) => 0; 388 lfs_dir_t dir; 389 lfs_dir_open(&lfs, &dir, "/") => 0; 390 struct lfs_info info; 391 lfs_dir_read(&lfs, &dir, &info) => 1; 392 assert(info.type == LFS_TYPE_DIR); 393 assert(strcmp(info.name, ".") == 0); 394 lfs_dir_read(&lfs, &dir, &info) => 1; 395 assert(info.type == LFS_TYPE_DIR); 396 assert(strcmp(info.name, "..") == 0); 397 for (int i = 0; i < N; i++) { 398 char path[1024]; 399 sprintf(path, "test%03d", i); 400 lfs_dir_read(&lfs, &dir, &info) => 1; 401 assert(info.type == LFS_TYPE_REG); 402 assert(strcmp(info.name, path) == 0); 403 } 404 lfs_dir_read(&lfs, &dir, &info) => 0; 405 lfs_dir_close(&lfs, &dir) => 0; 406 lfs_unmount(&lfs); 407 408 lfs_mount(&lfs, cfg) => 0; 409 for (int i = 0; i < N; i++) { 410 char oldpath[128]; 411 char newpath[128]; 412 sprintf(oldpath, "test%03d", i); 413 sprintf(newpath, "tedd%03d", i); 414 lfs_rename(&lfs, oldpath, newpath) => 0; 415 } 416 lfs_unmount(&lfs); 417 418 lfs_mount(&lfs, cfg) => 0; 419 lfs_dir_open(&lfs, &dir, "/") => 0; 420 lfs_dir_read(&lfs, &dir, &info) => 1; 421 assert(info.type == LFS_TYPE_DIR); 422 assert(strcmp(info.name, ".") == 0); 423 lfs_dir_read(&lfs, &dir, &info) => 1; 424 assert(info.type == LFS_TYPE_DIR); 425 assert(strcmp(info.name, "..") == 0); 426 for (int i = 0; i < N; i++) { 427 char path[1024]; 428 sprintf(path, "tedd%03d", i); 429 lfs_dir_read(&lfs, &dir, &info) => 1; 430 assert(info.type == LFS_TYPE_REG); 431 assert(strcmp(info.name, path) == 0); 432 } 433 lfs_dir_read(&lfs, &dir, &info) => 0; 434 lfs_dir_close(&lfs, &dir) => 0; 435 lfs_unmount(&lfs); 436''' 437 438[cases.test_dirs_file_reentrant] 439defines.N = [5, 25] 440if = 'N < BLOCK_COUNT/2' 441reentrant = true 442code = ''' 443 lfs_t lfs; 444 int err = lfs_mount(&lfs, cfg); 445 if (err) { 446 lfs_format(&lfs, cfg) => 0; 447 lfs_mount(&lfs, cfg) => 0; 448 } 449 450 for (int i = 0; i < N; i++) { 451 char path[1024]; 452 sprintf(path, "hi%03d", i); 453 lfs_file_t file; 454 lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0; 455 lfs_file_close(&lfs, &file) => 0; 456 } 457 458 for (int i = 0; i < N; i++) { 459 char path[1024]; 460 sprintf(path, "hello%03d", i); 461 err = lfs_remove(&lfs, path); 462 assert(err == 0 || err == LFS_ERR_NOENT); 463 } 464 465 lfs_dir_t dir; 466 lfs_dir_open(&lfs, &dir, "/") => 0; 467 struct lfs_info info; 468 lfs_dir_read(&lfs, &dir, &info) => 1; 469 assert(info.type == LFS_TYPE_DIR); 470 assert(strcmp(info.name, ".") == 0); 471 lfs_dir_read(&lfs, &dir, &info) => 1; 472 assert(info.type == LFS_TYPE_DIR); 473 assert(strcmp(info.name, "..") == 0); 474 for (int i = 0; i < N; i++) { 475 char path[1024]; 476 sprintf(path, "hi%03d", i); 477 lfs_dir_read(&lfs, &dir, &info) => 1; 478 assert(info.type == LFS_TYPE_REG); 479 assert(strcmp(info.name, path) == 0); 480 } 481 lfs_dir_read(&lfs, &dir, &info) => 0; 482 lfs_dir_close(&lfs, &dir) => 0; 483 484 for (int i = 0; i < N; i++) { 485 char oldpath[128]; 486 char newpath[128]; 487 sprintf(oldpath, "hi%03d", i); 488 sprintf(newpath, "hello%03d", i); 489 // YES this can overwrite an existing newpath 490 lfs_rename(&lfs, oldpath, newpath) => 0; 491 } 492 493 lfs_dir_open(&lfs, &dir, "/") => 0; 494 lfs_dir_read(&lfs, &dir, &info) => 1; 495 assert(info.type == LFS_TYPE_DIR); 496 assert(strcmp(info.name, ".") == 0); 497 lfs_dir_read(&lfs, &dir, &info) => 1; 498 assert(info.type == LFS_TYPE_DIR); 499 assert(strcmp(info.name, "..") == 0); 500 for (int i = 0; i < N; i++) { 501 char path[1024]; 502 sprintf(path, "hello%03d", i); 503 lfs_dir_read(&lfs, &dir, &info) => 1; 504 assert(info.type == LFS_TYPE_REG); 505 assert(strcmp(info.name, path) == 0); 506 } 507 lfs_dir_read(&lfs, &dir, &info) => 0; 508 lfs_dir_close(&lfs, &dir) => 0; 509 510 for (int i = 0; i < N; i++) { 511 char path[1024]; 512 sprintf(path, "hello%03d", i); 513 lfs_remove(&lfs, path) => 0; 514 } 515 516 lfs_dir_open(&lfs, &dir, "/") => 0; 517 lfs_dir_read(&lfs, &dir, &info) => 1; 518 assert(info.type == LFS_TYPE_DIR); 519 assert(strcmp(info.name, ".") == 0); 520 lfs_dir_read(&lfs, &dir, &info) => 1; 521 assert(info.type == LFS_TYPE_DIR); 522 assert(strcmp(info.name, "..") == 0); 523 lfs_dir_read(&lfs, &dir, &info) => 0; 524 lfs_dir_close(&lfs, &dir) => 0; 525 lfs_unmount(&lfs) => 0; 526''' 527 528[cases.test_dirs_nested] 529code = ''' 530 lfs_t lfs; 531 lfs_format(&lfs, cfg) => 0; 532 lfs_mount(&lfs, cfg) => 0; 533 lfs_mkdir(&lfs, "potato") => 0; 534 lfs_file_t file; 535 lfs_file_open(&lfs, &file, "burito", 536 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; 537 lfs_file_close(&lfs, &file) => 0; 538 lfs_unmount(&lfs) => 0; 539 540 lfs_mount(&lfs, cfg) => 0; 541 lfs_mkdir(&lfs, "potato/baked") => 0; 542 lfs_mkdir(&lfs, "potato/sweet") => 0; 543 lfs_mkdir(&lfs, "potato/fried") => 0; 544 lfs_unmount(&lfs) => 0; 545 546 lfs_mount(&lfs, cfg) => 0; 547 lfs_dir_t dir; 548 lfs_dir_open(&lfs, &dir, "potato") => 0; 549 struct lfs_info info; 550 lfs_dir_read(&lfs, &dir, &info) => 1; 551 assert(strcmp(info.name, ".") == 0); 552 info.type => LFS_TYPE_DIR; 553 lfs_dir_read(&lfs, &dir, &info) => 1; 554 assert(strcmp(info.name, "..") == 0); 555 info.type => LFS_TYPE_DIR; 556 lfs_dir_read(&lfs, &dir, &info) => 1; 557 assert(strcmp(info.name, "baked") == 0); 558 info.type => LFS_TYPE_DIR; 559 lfs_dir_read(&lfs, &dir, &info) => 1; 560 assert(strcmp(info.name, "fried") == 0); 561 info.type => LFS_TYPE_DIR; 562 lfs_dir_read(&lfs, &dir, &info) => 1; 563 assert(strcmp(info.name, "sweet") == 0); 564 info.type => LFS_TYPE_DIR; 565 lfs_dir_read(&lfs, &dir, &info) => 0; 566 lfs_dir_close(&lfs, &dir) => 0; 567 lfs_unmount(&lfs) => 0; 568 569 // try removing? 570 lfs_mount(&lfs, cfg) => 0; 571 lfs_remove(&lfs, "potato") => LFS_ERR_NOTEMPTY; 572 lfs_unmount(&lfs) => 0; 573 574 // try renaming? 575 lfs_mount(&lfs, cfg) => 0; 576 lfs_rename(&lfs, "potato", "coldpotato") => 0; 577 lfs_unmount(&lfs) => 0; 578 579 lfs_mount(&lfs, cfg) => 0; 580 lfs_rename(&lfs, "coldpotato", "warmpotato") => 0; 581 lfs_rename(&lfs, "warmpotato", "hotpotato") => 0; 582 lfs_unmount(&lfs) => 0; 583 584 lfs_mount(&lfs, cfg) => 0; 585 lfs_remove(&lfs, "potato") => LFS_ERR_NOENT; 586 lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOENT; 587 lfs_remove(&lfs, "warmpotato") => LFS_ERR_NOENT; 588 lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY; 589 lfs_unmount(&lfs) => 0; 590 591 // try cross-directory renaming 592 lfs_mount(&lfs, cfg) => 0; 593 lfs_mkdir(&lfs, "coldpotato") => 0; 594 lfs_rename(&lfs, "hotpotato/baked", "coldpotato/baked") => 0; 595 lfs_rename(&lfs, "coldpotato", "hotpotato") => LFS_ERR_NOTEMPTY; 596 lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOTEMPTY; 597 lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY; 598 lfs_rename(&lfs, "hotpotato/fried", "coldpotato/fried") => 0; 599 lfs_rename(&lfs, "coldpotato", "hotpotato") => LFS_ERR_NOTEMPTY; 600 lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOTEMPTY; 601 lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY; 602 lfs_rename(&lfs, "hotpotato/sweet", "coldpotato/sweet") => 0; 603 lfs_rename(&lfs, "coldpotato", "hotpotato") => 0; 604 lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOENT; 605 lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY; 606 lfs_unmount(&lfs) => 0; 607 608 lfs_mount(&lfs, cfg) => 0; 609 lfs_dir_open(&lfs, &dir, "hotpotato") => 0; 610 lfs_dir_read(&lfs, &dir, &info) => 1; 611 assert(strcmp(info.name, ".") == 0); 612 info.type => LFS_TYPE_DIR; 613 lfs_dir_read(&lfs, &dir, &info) => 1; 614 assert(strcmp(info.name, "..") == 0); 615 info.type => LFS_TYPE_DIR; 616 lfs_dir_read(&lfs, &dir, &info) => 1; 617 assert(strcmp(info.name, "baked") == 0); 618 info.type => LFS_TYPE_DIR; 619 lfs_dir_read(&lfs, &dir, &info) => 1; 620 assert(strcmp(info.name, "fried") == 0); 621 info.type => LFS_TYPE_DIR; 622 lfs_dir_read(&lfs, &dir, &info) => 1; 623 assert(strcmp(info.name, "sweet") == 0); 624 info.type => LFS_TYPE_DIR; 625 lfs_dir_read(&lfs, &dir, &info) => 0; 626 lfs_dir_close(&lfs, &dir) => 0; 627 lfs_unmount(&lfs) => 0; 628 629 // final remove 630 lfs_mount(&lfs, cfg) => 0; 631 lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY; 632 lfs_remove(&lfs, "hotpotato/baked") => 0; 633 lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY; 634 lfs_remove(&lfs, "hotpotato/fried") => 0; 635 lfs_remove(&lfs, "hotpotato") => LFS_ERR_NOTEMPTY; 636 lfs_remove(&lfs, "hotpotato/sweet") => 0; 637 lfs_remove(&lfs, "hotpotato") => 0; 638 lfs_unmount(&lfs) => 0; 639 640 lfs_mount(&lfs, cfg) => 0; 641 lfs_dir_open(&lfs, &dir, "/") => 0; 642 lfs_dir_read(&lfs, &dir, &info) => 1; 643 assert(strcmp(info.name, ".") == 0); 644 info.type => LFS_TYPE_DIR; 645 lfs_dir_read(&lfs, &dir, &info) => 1; 646 assert(strcmp(info.name, "..") == 0); 647 info.type => LFS_TYPE_DIR; 648 lfs_dir_read(&lfs, &dir, &info) => 1; 649 assert(strcmp(info.name, "burito") == 0); 650 info.type => LFS_TYPE_REG; 651 lfs_dir_read(&lfs, &dir, &info) => 0; 652 lfs_dir_close(&lfs, &dir) => 0; 653 lfs_unmount(&lfs) => 0; 654''' 655 656[cases.test_dirs_recursive_remove] 657defines.N = [10, 100] 658if = 'N < BLOCK_COUNT/2' 659code = ''' 660 lfs_t lfs; 661 lfs_format(&lfs, cfg) => 0; 662 lfs_mount(&lfs, cfg) => 0; 663 lfs_mkdir(&lfs, "prickly-pear") => 0; 664 for (int i = 0; i < N; i++) { 665 char path[1024]; 666 sprintf(path, "prickly-pear/cactus%03d", i); 667 lfs_mkdir(&lfs, path) => 0; 668 } 669 lfs_dir_t dir; 670 lfs_dir_open(&lfs, &dir, "prickly-pear") => 0; 671 struct lfs_info info; 672 lfs_dir_read(&lfs, &dir, &info) => 1; 673 assert(info.type == LFS_TYPE_DIR); 674 assert(strcmp(info.name, ".") == 0); 675 lfs_dir_read(&lfs, &dir, &info) => 1; 676 assert(info.type == LFS_TYPE_DIR); 677 assert(strcmp(info.name, "..") == 0); 678 for (int i = 0; i < N; i++) { 679 char path[1024]; 680 sprintf(path, "cactus%03d", i); 681 lfs_dir_read(&lfs, &dir, &info) => 1; 682 assert(info.type == LFS_TYPE_DIR); 683 assert(strcmp(info.name, path) == 0); 684 } 685 lfs_dir_read(&lfs, &dir, &info) => 0; 686 lfs_dir_close(&lfs, &dir) => 0; 687 lfs_unmount(&lfs); 688 689 lfs_mount(&lfs, cfg) => 0; 690 lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOTEMPTY; 691 692 lfs_dir_open(&lfs, &dir, "prickly-pear") => 0; 693 lfs_dir_read(&lfs, &dir, &info) => 1; 694 assert(info.type == LFS_TYPE_DIR); 695 assert(strcmp(info.name, ".") == 0); 696 lfs_dir_read(&lfs, &dir, &info) => 1; 697 assert(info.type == LFS_TYPE_DIR); 698 assert(strcmp(info.name, "..") == 0); 699 for (int i = 0; i < N; i++) { 700 char path[1024]; 701 sprintf(path, "cactus%03d", i); 702 lfs_dir_read(&lfs, &dir, &info) => 1; 703 assert(info.type == LFS_TYPE_DIR); 704 assert(strcmp(info.name, path) == 0); 705 sprintf(path, "prickly-pear/%s", info.name); 706 lfs_remove(&lfs, path) => 0; 707 } 708 lfs_dir_read(&lfs, &dir, &info) => 0; 709 lfs_dir_close(&lfs, &dir) => 0; 710 711 lfs_remove(&lfs, "prickly-pear") => 0; 712 lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOENT; 713 lfs_unmount(&lfs) => 0; 714 715 lfs_mount(&lfs, cfg) => 0; 716 lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOENT; 717 lfs_unmount(&lfs) => 0; 718''' 719 720[cases.test_dirs_other_errors] 721code = ''' 722 lfs_t lfs; 723 lfs_format(&lfs, cfg) => 0; 724 lfs_mount(&lfs, cfg) => 0; 725 lfs_mkdir(&lfs, "potato") => 0; 726 lfs_file_t file; 727 lfs_file_open(&lfs, &file, "burito", 728 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; 729 lfs_file_close(&lfs, &file) => 0; 730 lfs_unmount(&lfs) => 0; 731 732 lfs_mount(&lfs, cfg) => 0; 733 734 lfs_mkdir(&lfs, "potato") => LFS_ERR_EXIST; 735 lfs_mkdir(&lfs, "burito") => LFS_ERR_EXIST; 736 lfs_file_open(&lfs, &file, "burito", 737 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; 738 lfs_file_open(&lfs, &file, "potato", 739 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; 740 lfs_dir_t dir; 741 lfs_dir_open(&lfs, &dir, "tomato") => LFS_ERR_NOENT; 742 lfs_dir_open(&lfs, &dir, "burito") => LFS_ERR_NOTDIR; 743 lfs_file_open(&lfs, &file, "tomato", LFS_O_RDONLY) => LFS_ERR_NOENT; 744 lfs_file_open(&lfs, &file, "potato", LFS_O_RDONLY) => LFS_ERR_ISDIR; 745 lfs_file_open(&lfs, &file, "tomato", LFS_O_WRONLY) => LFS_ERR_NOENT; 746 lfs_file_open(&lfs, &file, "potato", LFS_O_WRONLY) => LFS_ERR_ISDIR; 747 lfs_file_open(&lfs, &file, "potato", 748 LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; 749 750 lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST; 751 lfs_file_open(&lfs, &file, "/", 752 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => LFS_ERR_EXIST; 753 lfs_file_open(&lfs, &file, "/", LFS_O_RDONLY) => LFS_ERR_ISDIR; 754 lfs_file_open(&lfs, &file, "/", LFS_O_WRONLY) => LFS_ERR_ISDIR; 755 lfs_file_open(&lfs, &file, "/", 756 LFS_O_WRONLY | LFS_O_CREAT) => LFS_ERR_ISDIR; 757 758 // check that errors did not corrupt directory 759 lfs_dir_open(&lfs, &dir, "/") => 0; 760 struct lfs_info info; 761 lfs_dir_read(&lfs, &dir, &info) => 1; 762 assert(info.type == LFS_TYPE_DIR); 763 assert(strcmp(info.name, ".") == 0); 764 lfs_dir_read(&lfs, &dir, &info) => 1; 765 assert(info.type == LFS_TYPE_DIR); 766 assert(strcmp(info.name, "..") == 0); 767 lfs_dir_read(&lfs, &dir, &info) => 1; 768 assert(info.type == LFS_TYPE_REG); 769 assert(strcmp(info.name, "burito") == 0); 770 lfs_dir_read(&lfs, &dir, &info) => 1; 771 assert(info.type == LFS_TYPE_DIR); 772 assert(strcmp(info.name, "potato") == 0); 773 lfs_dir_read(&lfs, &dir, &info) => 0; 774 lfs_dir_close(&lfs, &dir) => 0; 775 776 lfs_unmount(&lfs) => 0; 777 778 // or on disk 779 lfs_mount(&lfs, cfg) => 0; 780 lfs_dir_open(&lfs, &dir, "/") => 0; 781 lfs_dir_read(&lfs, &dir, &info) => 1; 782 assert(info.type == LFS_TYPE_DIR); 783 assert(strcmp(info.name, ".") == 0); 784 lfs_dir_read(&lfs, &dir, &info) => 1; 785 assert(info.type == LFS_TYPE_DIR); 786 assert(strcmp(info.name, "..") == 0); 787 lfs_dir_read(&lfs, &dir, &info) => 1; 788 assert(info.type == LFS_TYPE_REG); 789 assert(strcmp(info.name, "burito") == 0); 790 lfs_dir_read(&lfs, &dir, &info) => 1; 791 assert(info.type == LFS_TYPE_DIR); 792 assert(strcmp(info.name, "potato") == 0); 793 lfs_dir_read(&lfs, &dir, &info) => 0; 794 lfs_dir_close(&lfs, &dir) => 0; 795 lfs_unmount(&lfs) => 0; 796''' 797 798[cases.test_dirs_seek] 799defines.COUNT = [4, 128, 132] 800if = 'COUNT < BLOCK_COUNT/2' 801code = ''' 802 lfs_t lfs; 803 lfs_format(&lfs, cfg) => 0; 804 lfs_mount(&lfs, cfg) => 0; 805 lfs_mkdir(&lfs, "hello") => 0; 806 for (int i = 0; i < COUNT; i++) { 807 char path[1024]; 808 sprintf(path, "hello/kitty%03d", i); 809 lfs_mkdir(&lfs, path) => 0; 810 } 811 lfs_unmount(&lfs) => 0; 812 813 // try seeking to each dir entry 814 for (int j = 0; j < COUNT; j++) { 815 lfs_mount(&lfs, cfg) => 0; 816 lfs_dir_t dir; 817 lfs_dir_open(&lfs, &dir, "hello") => 0; 818 struct lfs_info info; 819 lfs_dir_read(&lfs, &dir, &info) => 1; 820 assert(strcmp(info.name, ".") == 0); 821 assert(info.type == LFS_TYPE_DIR); 822 lfs_dir_read(&lfs, &dir, &info) => 1; 823 assert(strcmp(info.name, "..") == 0); 824 assert(info.type == LFS_TYPE_DIR); 825 826 for (int i = 0; i < j; i++) { 827 char path[1024]; 828 sprintf(path, "kitty%03d", i); 829 lfs_dir_read(&lfs, &dir, &info) => 1; 830 assert(strcmp(info.name, path) == 0); 831 assert(info.type == LFS_TYPE_DIR); 832 } 833 lfs_soff_t pos = lfs_dir_tell(&lfs, &dir); 834 assert(pos >= 0); 835 836 lfs_dir_seek(&lfs, &dir, pos) => 0; 837 char path[1024]; 838 sprintf(path, "kitty%03d", j); 839 lfs_dir_read(&lfs, &dir, &info) => 1; 840 assert(strcmp(info.name, path) == 0); 841 assert(info.type == LFS_TYPE_DIR); 842 843 lfs_dir_rewind(&lfs, &dir) => 0; 844 sprintf(path, "kitty%03u", 0); 845 lfs_dir_read(&lfs, &dir, &info) => 1; 846 assert(strcmp(info.name, ".") == 0); 847 assert(info.type == LFS_TYPE_DIR); 848 lfs_dir_read(&lfs, &dir, &info) => 1; 849 assert(strcmp(info.name, "..") == 0); 850 assert(info.type == LFS_TYPE_DIR); 851 lfs_dir_read(&lfs, &dir, &info) => 1; 852 assert(strcmp(info.name, path) == 0); 853 assert(info.type == LFS_TYPE_DIR); 854 855 lfs_dir_seek(&lfs, &dir, pos) => 0; 856 sprintf(path, "kitty%03d", j); 857 lfs_dir_read(&lfs, &dir, &info) => 1; 858 assert(strcmp(info.name, path) == 0); 859 assert(info.type == LFS_TYPE_DIR); 860 861 lfs_dir_close(&lfs, &dir) => 0; 862 lfs_unmount(&lfs) => 0; 863 } 864 865 // try seeking to end of dir 866 lfs_mount(&lfs, cfg) => 0; 867 lfs_dir_t dir; 868 lfs_dir_open(&lfs, &dir, "hello") => 0; 869 struct lfs_info info; 870 lfs_dir_read(&lfs, &dir, &info) => 1; 871 assert(strcmp(info.name, ".") == 0); 872 assert(info.type == LFS_TYPE_DIR); 873 lfs_dir_read(&lfs, &dir, &info) => 1; 874 assert(strcmp(info.name, "..") == 0); 875 assert(info.type == LFS_TYPE_DIR); 876 877 for (int i = 0; i < COUNT; i++) { 878 char path[1024]; 879 sprintf(path, "kitty%03d", i); 880 lfs_dir_read(&lfs, &dir, &info) => 1; 881 assert(strcmp(info.name, path) == 0); 882 assert(info.type == LFS_TYPE_DIR); 883 } 884 lfs_soff_t pos = lfs_dir_tell(&lfs, &dir); 885 assert(pos >= 0); 886 887 lfs_dir_read(&lfs, &dir, &info) => 0; 888 889 lfs_dir_seek(&lfs, &dir, pos) => 0; 890 lfs_dir_read(&lfs, &dir, &info) => 0; 891 892 lfs_dir_rewind(&lfs, &dir) => 0; 893 char path[1024]; 894 sprintf(path, "kitty%03d", 0); 895 lfs_dir_read(&lfs, &dir, &info) => 1; 896 assert(strcmp(info.name, ".") == 0); 897 assert(info.type == LFS_TYPE_DIR); 898 lfs_dir_read(&lfs, &dir, &info) => 1; 899 assert(strcmp(info.name, "..") == 0); 900 assert(info.type == LFS_TYPE_DIR); 901 lfs_dir_read(&lfs, &dir, &info) => 1; 902 assert(strcmp(info.name, path) == 0); 903 assert(info.type == LFS_TYPE_DIR); 904 905 lfs_dir_seek(&lfs, &dir, pos) => 0; 906 lfs_dir_read(&lfs, &dir, &info) => 0; 907 908 lfs_dir_close(&lfs, &dir) => 0; 909 lfs_unmount(&lfs) => 0; 910''' 911 912[cases.test_dirs_toot_seek] 913defines.COUNT = [4, 128, 132] 914if = 'COUNT < BLOCK_COUNT/2' 915code = ''' 916 lfs_t lfs; 917 lfs_format(&lfs, cfg) => 0; 918 lfs_mount(&lfs, cfg) => 0; 919 for (int i = 0; i < COUNT; i++) { 920 char path[1024]; 921 sprintf(path, "hi%03d", i); 922 lfs_mkdir(&lfs, path) => 0; 923 } 924 lfs_unmount(&lfs) => 0; 925 926 for (int j = 0; j < COUNT; j++) { 927 lfs_mount(&lfs, cfg) => 0; 928 lfs_dir_t dir; 929 lfs_dir_open(&lfs, &dir, "/") => 0; 930 struct lfs_info info; 931 lfs_dir_read(&lfs, &dir, &info) => 1; 932 assert(strcmp(info.name, ".") == 0); 933 assert(info.type == LFS_TYPE_DIR); 934 lfs_dir_read(&lfs, &dir, &info) => 1; 935 assert(strcmp(info.name, "..") == 0); 936 assert(info.type == LFS_TYPE_DIR); 937 938 for (int i = 0; i < j; i++) { 939 char path[1024]; 940 sprintf(path, "hi%03d", i); 941 lfs_dir_read(&lfs, &dir, &info) => 1; 942 assert(strcmp(info.name, path) == 0); 943 assert(info.type == LFS_TYPE_DIR); 944 } 945 lfs_soff_t pos = lfs_dir_tell(&lfs, &dir); 946 assert(pos >= 0); 947 948 lfs_dir_seek(&lfs, &dir, pos) => 0; 949 char path[1024]; 950 sprintf(path, "hi%03d", j); 951 lfs_dir_read(&lfs, &dir, &info) => 1; 952 assert(strcmp(info.name, path) == 0); 953 assert(info.type == LFS_TYPE_DIR); 954 955 lfs_dir_rewind(&lfs, &dir) => 0; 956 sprintf(path, "hi%03u", 0); 957 lfs_dir_read(&lfs, &dir, &info) => 1; 958 assert(strcmp(info.name, ".") == 0); 959 assert(info.type == LFS_TYPE_DIR); 960 lfs_dir_read(&lfs, &dir, &info) => 1; 961 assert(strcmp(info.name, "..") == 0); 962 assert(info.type == LFS_TYPE_DIR); 963 lfs_dir_read(&lfs, &dir, &info) => 1; 964 assert(strcmp(info.name, path) == 0); 965 assert(info.type == LFS_TYPE_DIR); 966 967 lfs_dir_seek(&lfs, &dir, pos) => 0; 968 sprintf(path, "hi%03d", j); 969 lfs_dir_read(&lfs, &dir, &info) => 1; 970 assert(strcmp(info.name, path) == 0); 971 assert(info.type == LFS_TYPE_DIR); 972 973 lfs_dir_close(&lfs, &dir) => 0; 974 lfs_unmount(&lfs) => 0; 975 } 976 977 // try seeking to end of dir 978 lfs_mount(&lfs, cfg) => 0; 979 lfs_dir_t dir; 980 lfs_dir_open(&lfs, &dir, "/") => 0; 981 struct lfs_info info; 982 lfs_dir_read(&lfs, &dir, &info) => 1; 983 assert(strcmp(info.name, ".") == 0); 984 assert(info.type == LFS_TYPE_DIR); 985 lfs_dir_read(&lfs, &dir, &info) => 1; 986 assert(strcmp(info.name, "..") == 0); 987 assert(info.type == LFS_TYPE_DIR); 988 989 for (int i = 0; i < COUNT; i++) { 990 char path[1024]; 991 sprintf(path, "hi%03d", i); 992 lfs_dir_read(&lfs, &dir, &info) => 1; 993 assert(strcmp(info.name, path) == 0); 994 assert(info.type == LFS_TYPE_DIR); 995 } 996 lfs_soff_t pos = lfs_dir_tell(&lfs, &dir); 997 assert(pos >= 0); 998 999 lfs_dir_read(&lfs, &dir, &info) => 0; 1000 1001 lfs_dir_seek(&lfs, &dir, pos) => 0; 1002 lfs_dir_read(&lfs, &dir, &info) => 0; 1003 1004 lfs_dir_rewind(&lfs, &dir) => 0; 1005 char path[1024]; 1006 sprintf(path, "hi%03d", 0); 1007 lfs_dir_read(&lfs, &dir, &info) => 1; 1008 assert(strcmp(info.name, ".") == 0); 1009 assert(info.type == LFS_TYPE_DIR); 1010 lfs_dir_read(&lfs, &dir, &info) => 1; 1011 assert(strcmp(info.name, "..") == 0); 1012 assert(info.type == LFS_TYPE_DIR); 1013 lfs_dir_read(&lfs, &dir, &info) => 1; 1014 assert(strcmp(info.name, path) == 0); 1015 assert(info.type == LFS_TYPE_DIR); 1016 1017 lfs_dir_seek(&lfs, &dir, pos) => 0; 1018 lfs_dir_read(&lfs, &dir, &info) => 0; 1019 1020 lfs_dir_close(&lfs, &dir) => 0; 1021 lfs_unmount(&lfs) => 0; 1022''' 1023 1024