1 2# simple file seek 3[cases.test_seek_read] 4defines = [ 5 {COUNT=132, SKIP=4}, 6 {COUNT=132, SKIP=128}, 7 {COUNT=200, SKIP=10}, 8 {COUNT=200, SKIP=100}, 9 {COUNT=4, SKIP=1}, 10 {COUNT=4, SKIP=2}, 11] 12code = ''' 13 lfs_t lfs; 14 lfs_format(&lfs, cfg) => 0; 15 lfs_mount(&lfs, cfg) => 0; 16 lfs_file_t file; 17 lfs_file_open(&lfs, &file, "kitty", 18 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0; 19 size_t size = strlen("kittycatcat"); 20 uint8_t buffer[1024]; 21 memcpy(buffer, "kittycatcat", size); 22 for (int j = 0; j < COUNT; j++) { 23 lfs_file_write(&lfs, &file, buffer, size); 24 } 25 lfs_file_close(&lfs, &file) => 0; 26 lfs_unmount(&lfs) => 0; 27 28 lfs_mount(&lfs, cfg) => 0; 29 lfs_file_open(&lfs, &file, "kitty", LFS_O_RDONLY) => 0; 30 31 lfs_soff_t pos = -1; 32 size = strlen("kittycatcat"); 33 for (int i = 0; i < SKIP; i++) { 34 lfs_file_read(&lfs, &file, buffer, size) => size; 35 memcmp(buffer, "kittycatcat", size) => 0; 36 pos = lfs_file_tell(&lfs, &file); 37 } 38 assert(pos >= 0); 39 40 lfs_file_seek(&lfs, &file, pos, LFS_SEEK_SET) => pos; 41 lfs_file_read(&lfs, &file, buffer, size) => size; 42 memcmp(buffer, "kittycatcat", size) => 0; 43 44 lfs_file_rewind(&lfs, &file) => 0; 45 lfs_file_read(&lfs, &file, buffer, size) => size; 46 memcmp(buffer, "kittycatcat", size) => 0; 47 48 lfs_file_seek(&lfs, &file, 0, LFS_SEEK_CUR) => size; 49 lfs_file_read(&lfs, &file, buffer, size) => size; 50 memcmp(buffer, "kittycatcat", size) => 0; 51 52 lfs_file_seek(&lfs, &file, size, LFS_SEEK_CUR) => 3*size; 53 lfs_file_read(&lfs, &file, buffer, size) => size; 54 memcmp(buffer, "kittycatcat", size) => 0; 55 56 lfs_file_seek(&lfs, &file, pos, LFS_SEEK_SET) => pos; 57 lfs_file_read(&lfs, &file, buffer, size) => size; 58 memcmp(buffer, "kittycatcat", size) => 0; 59 60 lfs_file_seek(&lfs, &file, -size, LFS_SEEK_CUR) => pos; 61 lfs_file_read(&lfs, &file, buffer, size) => size; 62 memcmp(buffer, "kittycatcat", size) => 0; 63 64 lfs_file_seek(&lfs, &file, -size, LFS_SEEK_END) >= 0 => 1; 65 lfs_file_read(&lfs, &file, buffer, size) => size; 66 memcmp(buffer, "kittycatcat", size) => 0; 67 68 size = lfs_file_size(&lfs, &file); 69 lfs_file_seek(&lfs, &file, 0, LFS_SEEK_CUR) => size; 70 71 lfs_file_close(&lfs, &file) => 0; 72 lfs_unmount(&lfs) => 0; 73''' 74 75# simple file seek and write 76[cases.test_seek_write] 77defines = [ 78 {COUNT=132, SKIP=4}, 79 {COUNT=132, SKIP=128}, 80 {COUNT=200, SKIP=10}, 81 {COUNT=200, SKIP=100}, 82 {COUNT=4, SKIP=1}, 83 {COUNT=4, SKIP=2}, 84] 85code = ''' 86 lfs_t lfs; 87 lfs_format(&lfs, cfg) => 0; 88 lfs_mount(&lfs, cfg) => 0; 89 lfs_file_t file; 90 lfs_file_open(&lfs, &file, "kitty", 91 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0; 92 size_t size = strlen("kittycatcat"); 93 uint8_t buffer[1024]; 94 memcpy(buffer, "kittycatcat", size); 95 for (int j = 0; j < COUNT; j++) { 96 lfs_file_write(&lfs, &file, buffer, size); 97 } 98 lfs_file_close(&lfs, &file) => 0; 99 lfs_unmount(&lfs) => 0; 100 101 lfs_mount(&lfs, cfg) => 0; 102 lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0; 103 104 lfs_soff_t pos = -1; 105 size = strlen("kittycatcat"); 106 for (int i = 0; i < SKIP; i++) { 107 lfs_file_read(&lfs, &file, buffer, size) => size; 108 memcmp(buffer, "kittycatcat", size) => 0; 109 pos = lfs_file_tell(&lfs, &file); 110 } 111 assert(pos >= 0); 112 113 memcpy(buffer, "doggodogdog", size); 114 lfs_file_seek(&lfs, &file, pos, LFS_SEEK_SET) => pos; 115 lfs_file_write(&lfs, &file, buffer, size) => size; 116 117 lfs_file_seek(&lfs, &file, pos, LFS_SEEK_SET) => pos; 118 lfs_file_read(&lfs, &file, buffer, size) => size; 119 memcmp(buffer, "doggodogdog", size) => 0; 120 121 lfs_file_rewind(&lfs, &file) => 0; 122 lfs_file_read(&lfs, &file, buffer, size) => size; 123 memcmp(buffer, "kittycatcat", size) => 0; 124 125 lfs_file_seek(&lfs, &file, pos, LFS_SEEK_SET) => pos; 126 lfs_file_read(&lfs, &file, buffer, size) => size; 127 memcmp(buffer, "doggodogdog", size) => 0; 128 129 lfs_file_seek(&lfs, &file, -size, LFS_SEEK_END) >= 0 => 1; 130 lfs_file_read(&lfs, &file, buffer, size) => size; 131 memcmp(buffer, "kittycatcat", size) => 0; 132 133 size = lfs_file_size(&lfs, &file); 134 lfs_file_seek(&lfs, &file, 0, LFS_SEEK_CUR) => size; 135 136 lfs_file_close(&lfs, &file) => 0; 137 lfs_unmount(&lfs) => 0; 138''' 139 140# boundary seek and writes 141[cases.test_seek_boundary_write] 142defines.COUNT = 132 143code = ''' 144 lfs_t lfs; 145 lfs_format(&lfs, cfg) => 0; 146 lfs_mount(&lfs, cfg) => 0; 147 lfs_file_t file; 148 lfs_file_open(&lfs, &file, "kitty", 149 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0; 150 size_t size = strlen("kittycatcat"); 151 uint8_t buffer[1024]; 152 memcpy(buffer, "kittycatcat", size); 153 for (int j = 0; j < COUNT; j++) { 154 lfs_file_write(&lfs, &file, buffer, size); 155 } 156 lfs_file_close(&lfs, &file) => 0; 157 lfs_unmount(&lfs) => 0; 158 159 lfs_mount(&lfs, cfg) => 0; 160 lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0; 161 162 size = strlen("hedgehoghog"); 163 const lfs_soff_t offsets[] = {512, 1020, 513, 1021, 511, 1019, 1441}; 164 165 for (unsigned i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++) { 166 lfs_soff_t off = offsets[i]; 167 memcpy(buffer, "hedgehoghog", size); 168 lfs_file_seek(&lfs, &file, off, LFS_SEEK_SET) => off; 169 lfs_file_write(&lfs, &file, buffer, size) => size; 170 lfs_file_seek(&lfs, &file, off, LFS_SEEK_SET) => off; 171 lfs_file_read(&lfs, &file, buffer, size) => size; 172 memcmp(buffer, "hedgehoghog", size) => 0; 173 174 lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0; 175 lfs_file_read(&lfs, &file, buffer, size) => size; 176 memcmp(buffer, "kittycatcat", size) => 0; 177 178 lfs_file_seek(&lfs, &file, off, LFS_SEEK_SET) => off; 179 lfs_file_read(&lfs, &file, buffer, size) => size; 180 memcmp(buffer, "hedgehoghog", size) => 0; 181 182 lfs_file_sync(&lfs, &file) => 0; 183 184 lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0; 185 lfs_file_read(&lfs, &file, buffer, size) => size; 186 memcmp(buffer, "kittycatcat", size) => 0; 187 188 lfs_file_seek(&lfs, &file, off, LFS_SEEK_SET) => off; 189 lfs_file_read(&lfs, &file, buffer, size) => size; 190 memcmp(buffer, "hedgehoghog", size) => 0; 191 } 192 193 lfs_file_close(&lfs, &file) => 0; 194 lfs_unmount(&lfs) => 0; 195''' 196 197# out of bounds seek 198[cases.test_seek_out_of_bounds] 199defines = [ 200 {COUNT=132, SKIP=4}, 201 {COUNT=132, SKIP=128}, 202 {COUNT=200, SKIP=10}, 203 {COUNT=200, SKIP=100}, 204 {COUNT=4, SKIP=2}, 205 {COUNT=4, SKIP=3}, 206] 207code = ''' 208 lfs_t lfs; 209 lfs_format(&lfs, cfg) => 0; 210 lfs_mount(&lfs, cfg) => 0; 211 lfs_file_t file; 212 lfs_file_open(&lfs, &file, "kitty", 213 LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0; 214 size_t size = strlen("kittycatcat"); 215 uint8_t buffer[1024]; 216 memcpy(buffer, "kittycatcat", size); 217 for (int j = 0; j < COUNT; j++) { 218 lfs_file_write(&lfs, &file, buffer, size); 219 } 220 lfs_file_close(&lfs, &file) => 0; 221 lfs_unmount(&lfs) => 0; 222 lfs_mount(&lfs, cfg) => 0; 223 lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0; 224 225 size = strlen("kittycatcat"); 226 lfs_file_size(&lfs, &file) => COUNT*size; 227 lfs_file_seek(&lfs, &file, (COUNT+SKIP)*size, 228 LFS_SEEK_SET) => (COUNT+SKIP)*size; 229 lfs_file_read(&lfs, &file, buffer, size) => 0; 230 231 memcpy(buffer, "porcupineee", size); 232 lfs_file_write(&lfs, &file, buffer, size) => size; 233 234 lfs_file_seek(&lfs, &file, (COUNT+SKIP)*size, 235 LFS_SEEK_SET) => (COUNT+SKIP)*size; 236 lfs_file_read(&lfs, &file, buffer, size) => size; 237 memcmp(buffer, "porcupineee", size) => 0; 238 239 lfs_file_seek(&lfs, &file, COUNT*size, 240 LFS_SEEK_SET) => COUNT*size; 241 lfs_file_read(&lfs, &file, buffer, size) => size; 242 memcmp(buffer, "\0\0\0\0\0\0\0\0\0\0\0", size) => 0; 243 244 lfs_file_seek(&lfs, &file, -((COUNT+SKIP)*size), 245 LFS_SEEK_CUR) => LFS_ERR_INVAL; 246 lfs_file_tell(&lfs, &file) => (COUNT+1)*size; 247 248 lfs_file_seek(&lfs, &file, -((COUNT+2*SKIP)*size), 249 LFS_SEEK_END) => LFS_ERR_INVAL; 250 lfs_file_tell(&lfs, &file) => (COUNT+1)*size; 251 252 lfs_file_close(&lfs, &file) => 0; 253 lfs_unmount(&lfs) => 0; 254''' 255 256# inline write and seek 257[cases.test_seek_inline_write] 258defines.SIZE = [2, 4, 128, 132] 259code = ''' 260 lfs_t lfs; 261 lfs_format(&lfs, cfg) => 0; 262 lfs_mount(&lfs, cfg) => 0; 263 lfs_file_t file; 264 lfs_file_open(&lfs, &file, "tinykitty", 265 LFS_O_RDWR | LFS_O_CREAT) => 0; 266 int j = 0; 267 int k = 0; 268 269 uint8_t buffer[1024]; 270 memcpy(buffer, "abcdefghijklmnopqrstuvwxyz", 26); 271 for (unsigned i = 0; i < SIZE; i++) { 272 lfs_file_write(&lfs, &file, &buffer[j++ % 26], 1) => 1; 273 lfs_file_tell(&lfs, &file) => i+1; 274 lfs_file_size(&lfs, &file) => i+1; 275 } 276 277 lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0; 278 lfs_file_tell(&lfs, &file) => 0; 279 lfs_file_size(&lfs, &file) => SIZE; 280 for (unsigned i = 0; i < SIZE; i++) { 281 uint8_t c; 282 lfs_file_read(&lfs, &file, &c, 1) => 1; 283 c => buffer[k++ % 26]; 284 } 285 286 lfs_file_sync(&lfs, &file) => 0; 287 lfs_file_tell(&lfs, &file) => SIZE; 288 lfs_file_size(&lfs, &file) => SIZE; 289 290 lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0; 291 for (unsigned i = 0; i < SIZE; i++) { 292 lfs_file_write(&lfs, &file, &buffer[j++ % 26], 1) => 1; 293 lfs_file_tell(&lfs, &file) => i+1; 294 lfs_file_size(&lfs, &file) => SIZE; 295 lfs_file_sync(&lfs, &file) => 0; 296 lfs_file_tell(&lfs, &file) => i+1; 297 lfs_file_size(&lfs, &file) => SIZE; 298 if (i < SIZE-2) { 299 uint8_t c[3]; 300 lfs_file_seek(&lfs, &file, -1, LFS_SEEK_CUR) => i; 301 lfs_file_read(&lfs, &file, &c, 3) => 3; 302 lfs_file_tell(&lfs, &file) => i+3; 303 lfs_file_size(&lfs, &file) => SIZE; 304 lfs_file_seek(&lfs, &file, i+1, LFS_SEEK_SET) => i+1; 305 lfs_file_tell(&lfs, &file) => i+1; 306 lfs_file_size(&lfs, &file) => SIZE; 307 } 308 } 309 310 lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0; 311 lfs_file_tell(&lfs, &file) => 0; 312 lfs_file_size(&lfs, &file) => SIZE; 313 for (unsigned i = 0; i < SIZE; i++) { 314 uint8_t c; 315 lfs_file_read(&lfs, &file, &c, 1) => 1; 316 c => buffer[k++ % 26]; 317 } 318 319 lfs_file_sync(&lfs, &file) => 0; 320 lfs_file_tell(&lfs, &file) => SIZE; 321 lfs_file_size(&lfs, &file) => SIZE; 322 323 lfs_file_close(&lfs, &file) => 0; 324 lfs_unmount(&lfs) => 0; 325''' 326 327# file seek and write with power-loss 328[cases.test_seek_reentrant_write] 329# must be power-of-2 for quadratic probing to be exhaustive 330defines.COUNT = [4, 64, 128] 331reentrant = true 332code = ''' 333 lfs_t lfs; 334 int err = lfs_mount(&lfs, cfg); 335 if (err) { 336 lfs_format(&lfs, cfg) => 0; 337 lfs_mount(&lfs, cfg) => 0; 338 } 339 lfs_file_t file; 340 uint8_t buffer[1024]; 341 err = lfs_file_open(&lfs, &file, "kitty", LFS_O_RDONLY); 342 assert(!err || err == LFS_ERR_NOENT); 343 if (!err) { 344 if (lfs_file_size(&lfs, &file) != 0) { 345 lfs_file_size(&lfs, &file) => 11*COUNT; 346 for (int j = 0; j < COUNT; j++) { 347 memset(buffer, 0, 11+1); 348 lfs_file_read(&lfs, &file, buffer, 11) => 11; 349 assert(memcmp(buffer, "kittycatcat", 11) == 0 || 350 memcmp(buffer, "doggodogdog", 11) == 0); 351 } 352 } 353 lfs_file_close(&lfs, &file) => 0; 354 } 355 356 lfs_file_open(&lfs, &file, "kitty", LFS_O_WRONLY | LFS_O_CREAT) => 0; 357 if (lfs_file_size(&lfs, &file) == 0) { 358 for (int j = 0; j < COUNT; j++) { 359 strcpy((char*)buffer, "kittycatcat"); 360 size_t size = strlen((char*)buffer); 361 lfs_file_write(&lfs, &file, buffer, size) => size; 362 } 363 } 364 lfs_file_close(&lfs, &file) => 0; 365 366 strcpy((char*)buffer, "doggodogdog"); 367 size_t size = strlen((char*)buffer); 368 369 lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0; 370 lfs_file_size(&lfs, &file) => COUNT*size; 371 // seek and write using quadratic probing to touch all 372 // 11-byte words in the file 373 lfs_off_t off = 0; 374 for (int j = 0; j < COUNT; j++) { 375 off = (5*off + 1) % COUNT; 376 lfs_file_seek(&lfs, &file, off*size, LFS_SEEK_SET) => off*size; 377 lfs_file_read(&lfs, &file, buffer, size) => size; 378 assert(memcmp(buffer, "kittycatcat", size) == 0 || 379 memcmp(buffer, "doggodogdog", size) == 0); 380 if (memcmp(buffer, "doggodogdog", size) != 0) { 381 lfs_file_seek(&lfs, &file, off*size, LFS_SEEK_SET) => off*size; 382 strcpy((char*)buffer, "doggodogdog"); 383 lfs_file_write(&lfs, &file, buffer, size) => size; 384 lfs_file_seek(&lfs, &file, off*size, LFS_SEEK_SET) => off*size; 385 lfs_file_read(&lfs, &file, buffer, size) => size; 386 assert(memcmp(buffer, "doggodogdog", size) == 0); 387 lfs_file_sync(&lfs, &file) => 0; 388 lfs_file_seek(&lfs, &file, off*size, LFS_SEEK_SET) => off*size; 389 lfs_file_read(&lfs, &file, buffer, size) => size; 390 assert(memcmp(buffer, "doggodogdog", size) == 0); 391 } 392 } 393 lfs_file_close(&lfs, &file) => 0; 394 395 lfs_file_open(&lfs, &file, "kitty", LFS_O_RDWR) => 0; 396 lfs_file_size(&lfs, &file) => COUNT*size; 397 for (int j = 0; j < COUNT; j++) { 398 lfs_file_read(&lfs, &file, buffer, size) => size; 399 assert(memcmp(buffer, "doggodogdog", size) == 0); 400 } 401 lfs_file_close(&lfs, &file) => 0; 402 lfs_unmount(&lfs) => 0; 403''' 404