1 2[[case]] # simple file test 3code = ''' 4 lfs_format(&lfs, &cfg) => 0; 5 lfs_mount(&lfs, &cfg) => 0; 6 lfs_file_open(&lfs, &file, "hello", 7 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; 8 size = strlen("Hello World!")+1; 9 strcpy((char*)buffer, "Hello World!"); 10 lfs_file_write(&lfs, &file, buffer, size) => size; 11 lfs_file_close(&lfs, &file) => 0; 12 lfs_unmount(&lfs) => 0; 13 14 lfs_mount(&lfs, &cfg) => 0; 15 lfs_file_open(&lfs, &file, "hello", LFS_O_RDONLY) => 0; 16 lfs_file_read(&lfs, &file, buffer, size) => size; 17 assert(strcmp((char*)buffer, "Hello World!") == 0); 18 lfs_file_close(&lfs, &file) => 0; 19 lfs_unmount(&lfs) => 0; 20''' 21 22[[case]] # larger files 23define.SIZE = [32, 8192, 262144, 0, 7, 8193] 24define.CHUNKSIZE = [31, 16, 33, 1, 1023] 25code = ''' 26 lfs_format(&lfs, &cfg) => 0; 27 28 // write 29 lfs_mount(&lfs, &cfg) => 0; 30 lfs_file_open(&lfs, &file, "avacado", 31 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; 32 srand(1); 33 for (lfs_size_t i = 0; i < SIZE; i += CHUNKSIZE) { 34 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i); 35 for (lfs_size_t b = 0; b < chunk; b++) { 36 buffer[b] = rand() & 0xff; 37 } 38 lfs_file_write(&lfs, &file, buffer, chunk) => chunk; 39 } 40 lfs_file_close(&lfs, &file) => 0; 41 lfs_unmount(&lfs) => 0; 42 43 // read 44 lfs_mount(&lfs, &cfg) => 0; 45 lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0; 46 lfs_file_size(&lfs, &file) => SIZE; 47 srand(1); 48 for (lfs_size_t i = 0; i < SIZE; i += CHUNKSIZE) { 49 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i); 50 lfs_file_read(&lfs, &file, buffer, chunk) => chunk; 51 for (lfs_size_t b = 0; b < chunk; b++) { 52 assert(buffer[b] == (rand() & 0xff)); 53 } 54 } 55 lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0; 56 lfs_file_close(&lfs, &file) => 0; 57 lfs_unmount(&lfs) => 0; 58''' 59 60[[case]] # rewriting files 61define.SIZE1 = [32, 8192, 131072, 0, 7, 8193] 62define.SIZE2 = [32, 8192, 131072, 0, 7, 8193] 63define.CHUNKSIZE = [31, 16, 1] 64code = ''' 65 lfs_format(&lfs, &cfg) => 0; 66 67 // write 68 lfs_mount(&lfs, &cfg) => 0; 69 lfs_file_open(&lfs, &file, "avacado", 70 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; 71 srand(1); 72 for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) { 73 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i); 74 for (lfs_size_t b = 0; b < chunk; b++) { 75 buffer[b] = rand() & 0xff; 76 } 77 lfs_file_write(&lfs, &file, buffer, chunk) => chunk; 78 } 79 lfs_file_close(&lfs, &file) => 0; 80 lfs_unmount(&lfs) => 0; 81 82 // read 83 lfs_mount(&lfs, &cfg) => 0; 84 lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0; 85 lfs_file_size(&lfs, &file) => SIZE1; 86 srand(1); 87 for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) { 88 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i); 89 lfs_file_read(&lfs, &file, buffer, chunk) => chunk; 90 for (lfs_size_t b = 0; b < chunk; b++) { 91 assert(buffer[b] == (rand() & 0xff)); 92 } 93 } 94 lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0; 95 lfs_file_close(&lfs, &file) => 0; 96 lfs_unmount(&lfs) => 0; 97 98 // rewrite 99 lfs_mount(&lfs, &cfg) => 0; 100 lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY) => 0; 101 srand(2); 102 for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) { 103 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE2-i); 104 for (lfs_size_t b = 0; b < chunk; b++) { 105 buffer[b] = rand() & 0xff; 106 } 107 lfs_file_write(&lfs, &file, buffer, chunk) => chunk; 108 } 109 lfs_file_close(&lfs, &file) => 0; 110 lfs_unmount(&lfs) => 0; 111 112 // read 113 lfs_mount(&lfs, &cfg) => 0; 114 lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0; 115 lfs_file_size(&lfs, &file) => lfs_max(SIZE1, SIZE2); 116 srand(2); 117 for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) { 118 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE2-i); 119 lfs_file_read(&lfs, &file, buffer, chunk) => chunk; 120 for (lfs_size_t b = 0; b < chunk; b++) { 121 assert(buffer[b] == (rand() & 0xff)); 122 } 123 } 124 if (SIZE1 > SIZE2) { 125 srand(1); 126 for (lfs_size_t b = 0; b < SIZE2; b++) { 127 rand(); 128 } 129 for (lfs_size_t i = SIZE2; i < SIZE1; i += CHUNKSIZE) { 130 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i); 131 lfs_file_read(&lfs, &file, buffer, chunk) => chunk; 132 for (lfs_size_t b = 0; b < chunk; b++) { 133 assert(buffer[b] == (rand() & 0xff)); 134 } 135 } 136 } 137 lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0; 138 lfs_file_close(&lfs, &file) => 0; 139 lfs_unmount(&lfs) => 0; 140''' 141 142[[case]] # appending files 143define.SIZE1 = [32, 8192, 131072, 0, 7, 8193] 144define.SIZE2 = [32, 8192, 131072, 0, 7, 8193] 145define.CHUNKSIZE = [31, 16, 1] 146code = ''' 147 lfs_format(&lfs, &cfg) => 0; 148 149 // write 150 lfs_mount(&lfs, &cfg) => 0; 151 lfs_file_open(&lfs, &file, "avacado", 152 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; 153 srand(1); 154 for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) { 155 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i); 156 for (lfs_size_t b = 0; b < chunk; b++) { 157 buffer[b] = rand() & 0xff; 158 } 159 lfs_file_write(&lfs, &file, buffer, chunk) => chunk; 160 } 161 lfs_file_close(&lfs, &file) => 0; 162 lfs_unmount(&lfs) => 0; 163 164 // read 165 lfs_mount(&lfs, &cfg) => 0; 166 lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0; 167 lfs_file_size(&lfs, &file) => SIZE1; 168 srand(1); 169 for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) { 170 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i); 171 lfs_file_read(&lfs, &file, buffer, chunk) => chunk; 172 for (lfs_size_t b = 0; b < chunk; b++) { 173 assert(buffer[b] == (rand() & 0xff)); 174 } 175 } 176 lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0; 177 lfs_file_close(&lfs, &file) => 0; 178 lfs_unmount(&lfs) => 0; 179 180 // append 181 lfs_mount(&lfs, &cfg) => 0; 182 lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY | LFS_O_APPEND) => 0; 183 srand(2); 184 for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) { 185 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE2-i); 186 for (lfs_size_t b = 0; b < chunk; b++) { 187 buffer[b] = rand() & 0xff; 188 } 189 lfs_file_write(&lfs, &file, buffer, chunk) => chunk; 190 } 191 lfs_file_close(&lfs, &file) => 0; 192 lfs_unmount(&lfs) => 0; 193 194 // read 195 lfs_mount(&lfs, &cfg) => 0; 196 lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0; 197 lfs_file_size(&lfs, &file) => SIZE1 + SIZE2; 198 srand(1); 199 for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) { 200 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i); 201 lfs_file_read(&lfs, &file, buffer, chunk) => chunk; 202 for (lfs_size_t b = 0; b < chunk; b++) { 203 assert(buffer[b] == (rand() & 0xff)); 204 } 205 } 206 srand(2); 207 for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) { 208 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE2-i); 209 lfs_file_read(&lfs, &file, buffer, chunk) => chunk; 210 for (lfs_size_t b = 0; b < chunk; b++) { 211 assert(buffer[b] == (rand() & 0xff)); 212 } 213 } 214 lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0; 215 lfs_file_close(&lfs, &file) => 0; 216 lfs_unmount(&lfs) => 0; 217''' 218 219[[case]] # truncating files 220define.SIZE1 = [32, 8192, 131072, 0, 7, 8193] 221define.SIZE2 = [32, 8192, 131072, 0, 7, 8193] 222define.CHUNKSIZE = [31, 16, 1] 223code = ''' 224 lfs_format(&lfs, &cfg) => 0; 225 226 // write 227 lfs_mount(&lfs, &cfg) => 0; 228 lfs_file_open(&lfs, &file, "avacado", 229 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; 230 srand(1); 231 for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) { 232 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i); 233 for (lfs_size_t b = 0; b < chunk; b++) { 234 buffer[b] = rand() & 0xff; 235 } 236 lfs_file_write(&lfs, &file, buffer, chunk) => chunk; 237 } 238 lfs_file_close(&lfs, &file) => 0; 239 lfs_unmount(&lfs) => 0; 240 241 // read 242 lfs_mount(&lfs, &cfg) => 0; 243 lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0; 244 lfs_file_size(&lfs, &file) => SIZE1; 245 srand(1); 246 for (lfs_size_t i = 0; i < SIZE1; i += CHUNKSIZE) { 247 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE1-i); 248 lfs_file_read(&lfs, &file, buffer, chunk) => chunk; 249 for (lfs_size_t b = 0; b < chunk; b++) { 250 assert(buffer[b] == (rand() & 0xff)); 251 } 252 } 253 lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0; 254 lfs_file_close(&lfs, &file) => 0; 255 lfs_unmount(&lfs) => 0; 256 257 // truncate 258 lfs_mount(&lfs, &cfg) => 0; 259 lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY | LFS_O_TRUNC) => 0; 260 srand(2); 261 for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) { 262 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE2-i); 263 for (lfs_size_t b = 0; b < chunk; b++) { 264 buffer[b] = rand() & 0xff; 265 } 266 lfs_file_write(&lfs, &file, buffer, chunk) => chunk; 267 } 268 lfs_file_close(&lfs, &file) => 0; 269 lfs_unmount(&lfs) => 0; 270 271 // read 272 lfs_mount(&lfs, &cfg) => 0; 273 lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0; 274 lfs_file_size(&lfs, &file) => SIZE2; 275 srand(2); 276 for (lfs_size_t i = 0; i < SIZE2; i += CHUNKSIZE) { 277 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE2-i); 278 lfs_file_read(&lfs, &file, buffer, chunk) => chunk; 279 for (lfs_size_t b = 0; b < chunk; b++) { 280 assert(buffer[b] == (rand() & 0xff)); 281 } 282 } 283 lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0; 284 lfs_file_close(&lfs, &file) => 0; 285 lfs_unmount(&lfs) => 0; 286''' 287 288[[case]] # reentrant file writing 289define.SIZE = [32, 0, 7, 2049] 290define.CHUNKSIZE = [31, 16, 65] 291reentrant = true 292code = ''' 293 err = lfs_mount(&lfs, &cfg); 294 if (err) { 295 lfs_format(&lfs, &cfg) => 0; 296 lfs_mount(&lfs, &cfg) => 0; 297 } 298 299 err = lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY); 300 assert(err == LFS_ERR_NOENT || err == 0); 301 if (err == 0) { 302 // can only be 0 (new file) or full size 303 size = lfs_file_size(&lfs, &file); 304 assert(size == 0 || size == SIZE); 305 lfs_file_close(&lfs, &file) => 0; 306 } 307 308 // write 309 lfs_file_open(&lfs, &file, "avacado", LFS_O_WRONLY | LFS_O_CREAT) => 0; 310 srand(1); 311 for (lfs_size_t i = 0; i < SIZE; i += CHUNKSIZE) { 312 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i); 313 for (lfs_size_t b = 0; b < chunk; b++) { 314 buffer[b] = rand() & 0xff; 315 } 316 lfs_file_write(&lfs, &file, buffer, chunk) => chunk; 317 } 318 lfs_file_close(&lfs, &file) => 0; 319 320 // read 321 lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0; 322 lfs_file_size(&lfs, &file) => SIZE; 323 srand(1); 324 for (lfs_size_t i = 0; i < SIZE; i += CHUNKSIZE) { 325 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i); 326 lfs_file_read(&lfs, &file, buffer, chunk) => chunk; 327 for (lfs_size_t b = 0; b < chunk; b++) { 328 assert(buffer[b] == (rand() & 0xff)); 329 } 330 } 331 lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0; 332 lfs_file_close(&lfs, &file) => 0; 333 lfs_unmount(&lfs) => 0; 334''' 335 336[[case]] # reentrant file writing with syncs 337define = [ 338 # append (O(n)) 339 {MODE='LFS_O_APPEND', SIZE=[32, 0, 7, 2049], CHUNKSIZE=[31, 16, 65]}, 340 # truncate (O(n^2)) 341 {MODE='LFS_O_TRUNC', SIZE=[32, 0, 7, 200], CHUNKSIZE=[31, 16, 65]}, 342 # rewrite (O(n^2)) 343 {MODE=0, SIZE=[32, 0, 7, 200], CHUNKSIZE=[31, 16, 65]}, 344] 345reentrant = true 346code = ''' 347 err = lfs_mount(&lfs, &cfg); 348 if (err) { 349 lfs_format(&lfs, &cfg) => 0; 350 lfs_mount(&lfs, &cfg) => 0; 351 } 352 353 err = lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY); 354 assert(err == LFS_ERR_NOENT || err == 0); 355 if (err == 0) { 356 // with syncs we could be any size, but it at least must be valid data 357 size = lfs_file_size(&lfs, &file); 358 assert(size <= SIZE); 359 srand(1); 360 for (lfs_size_t i = 0; i < size; i += CHUNKSIZE) { 361 lfs_size_t chunk = lfs_min(CHUNKSIZE, size-i); 362 lfs_file_read(&lfs, &file, buffer, chunk) => chunk; 363 for (lfs_size_t b = 0; b < chunk; b++) { 364 assert(buffer[b] == (rand() & 0xff)); 365 } 366 } 367 lfs_file_close(&lfs, &file) => 0; 368 } 369 370 // write 371 lfs_file_open(&lfs, &file, "avacado", 372 LFS_O_WRONLY | LFS_O_CREAT | MODE) => 0; 373 size = lfs_file_size(&lfs, &file); 374 assert(size <= SIZE); 375 srand(1); 376 lfs_size_t skip = (MODE == LFS_O_APPEND) ? size : 0; 377 for (lfs_size_t b = 0; b < skip; b++) { 378 rand(); 379 } 380 for (lfs_size_t i = skip; i < SIZE; i += CHUNKSIZE) { 381 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i); 382 for (lfs_size_t b = 0; b < chunk; b++) { 383 buffer[b] = rand() & 0xff; 384 } 385 lfs_file_write(&lfs, &file, buffer, chunk) => chunk; 386 lfs_file_sync(&lfs, &file) => 0; 387 } 388 lfs_file_close(&lfs, &file) => 0; 389 390 // read 391 lfs_file_open(&lfs, &file, "avacado", LFS_O_RDONLY) => 0; 392 lfs_file_size(&lfs, &file) => SIZE; 393 srand(1); 394 for (lfs_size_t i = 0; i < SIZE; i += CHUNKSIZE) { 395 lfs_size_t chunk = lfs_min(CHUNKSIZE, SIZE-i); 396 lfs_file_read(&lfs, &file, buffer, chunk) => chunk; 397 for (lfs_size_t b = 0; b < chunk; b++) { 398 assert(buffer[b] == (rand() & 0xff)); 399 } 400 } 401 lfs_file_read(&lfs, &file, buffer, CHUNKSIZE) => 0; 402 lfs_file_close(&lfs, &file) => 0; 403 lfs_unmount(&lfs) => 0; 404''' 405 406[[case]] # many files 407define.N = 300 408code = ''' 409 lfs_format(&lfs, &cfg) => 0; 410 // create N files of 7 bytes 411 lfs_mount(&lfs, &cfg) => 0; 412 for (int i = 0; i < N; i++) { 413 sprintf(path, "file_%03d", i); 414 lfs_file_open(&lfs, &file, path, 415 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; 416 char wbuffer[1024]; 417 size = 7; 418 snprintf(wbuffer, size, "Hi %03d", i); 419 lfs_file_write(&lfs, &file, wbuffer, size) => size; 420 lfs_file_close(&lfs, &file) => 0; 421 422 char rbuffer[1024]; 423 lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0; 424 lfs_file_read(&lfs, &file, rbuffer, size) => size; 425 assert(strcmp(rbuffer, wbuffer) == 0); 426 lfs_file_close(&lfs, &file) => 0; 427 } 428 lfs_unmount(&lfs) => 0; 429''' 430 431[[case]] # many files with power cycle 432define.N = 300 433code = ''' 434 lfs_format(&lfs, &cfg) => 0; 435 // create N files of 7 bytes 436 lfs_mount(&lfs, &cfg) => 0; 437 for (int i = 0; i < N; i++) { 438 sprintf(path, "file_%03d", i); 439 lfs_file_open(&lfs, &file, path, 440 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; 441 char wbuffer[1024]; 442 size = 7; 443 snprintf(wbuffer, size, "Hi %03d", i); 444 lfs_file_write(&lfs, &file, wbuffer, size) => size; 445 lfs_file_close(&lfs, &file) => 0; 446 lfs_unmount(&lfs) => 0; 447 448 char rbuffer[1024]; 449 lfs_mount(&lfs, &cfg) => 0; 450 lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0; 451 lfs_file_read(&lfs, &file, rbuffer, size) => size; 452 assert(strcmp(rbuffer, wbuffer) == 0); 453 lfs_file_close(&lfs, &file) => 0; 454 } 455 lfs_unmount(&lfs) => 0; 456''' 457 458[[case]] # many files with power loss 459define.N = 300 460reentrant = true 461code = ''' 462 err = lfs_mount(&lfs, &cfg); 463 if (err) { 464 lfs_format(&lfs, &cfg) => 0; 465 lfs_mount(&lfs, &cfg) => 0; 466 } 467 // create N files of 7 bytes 468 for (int i = 0; i < N; i++) { 469 sprintf(path, "file_%03d", i); 470 err = lfs_file_open(&lfs, &file, path, LFS_O_WRONLY | LFS_O_CREAT); 471 char wbuffer[1024]; 472 size = 7; 473 snprintf(wbuffer, size, "Hi %03d", i); 474 if ((lfs_size_t)lfs_file_size(&lfs, &file) != size) { 475 lfs_file_write(&lfs, &file, wbuffer, size) => size; 476 } 477 lfs_file_close(&lfs, &file) => 0; 478 479 char rbuffer[1024]; 480 lfs_file_open(&lfs, &file, path, LFS_O_RDONLY) => 0; 481 lfs_file_read(&lfs, &file, rbuffer, size) => size; 482 assert(strcmp(rbuffer, wbuffer) == 0); 483 lfs_file_close(&lfs, &file) => 0; 484 } 485 lfs_unmount(&lfs) => 0; 486''' 487