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