116b816a993123f5d855348a63caa7940e9b07d6
[bertos.git] / bertos / fs / battfs_test.c
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2007, 2008 Develer S.r.l. (http://www.develer.com/)
30  * -->
31  *
32  * \brief BattFS Test.
33  *
34  * \version $Id$
35  * \author Francesco Sacchi <batt@develer.com>
36  */
37
38 #include <fs/battfs.h>
39
40 #include <cfg/debug.h>
41 #include <cfg/test.h>
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46
47 #define FILE_SIZE 32768
48 #define PAGE_SIZE 128
49 #define PAGE_COUNT FILE_SIZE / PAGE_SIZE
50
51 #if UNIT_TEST
52
53 FILE *fp;
54 const char test_filename[]="battfs_disk.bin";
55
56 static uint8_t page_buffer[PAGE_SIZE];
57
58 static bool disk_open(struct BattFsSuper *d)
59 {
60         fp = fopen(test_filename, "r+b");
61         ASSERT(fp);
62         fseek(fp, 0, SEEK_END);
63         d->page_size = PAGE_SIZE;
64         d->page_count = ftell(fp) / d->page_size;
65         d->page_array = malloc(d->page_count * sizeof(pgcnt_t));
66         //TRACEMSG("page_size:%d, page_count:%d\n", d->page_size, d->page_count);
67         return (fp && d->page_array);
68 }
69
70 static size_t disk_page_read(struct BattFsSuper *d, pgcnt_t page, pgaddr_t addr, void *buf, size_t size)
71 {
72         //TRACEMSG("page:%d, addr:%d, size:%d", page, addr, size);
73         fseek(fp, page * d->page_size + addr, SEEK_SET);
74         return fread(buf, 1, size, fp);
75 }
76
77 static size_t disk_buffer_write(struct BattFsSuper *d, pgaddr_t addr, const void *buf, size_t size)
78 {
79         //TRACEMSG("addr:%d, size:%d", addr, size);
80         ASSERT(addr + size <= d->page_size);
81         memcpy(&page_buffer[addr], buf, size);
82
83         return size;
84 }
85
86 static size_t disk_buffer_read(struct BattFsSuper *d, pgaddr_t addr, void *buf, size_t size)
87 {
88         //TRACEMSG("addr:%d, size:%d", addr, size);
89         ASSERT(addr + size <= d->page_size);
90         memcpy(buf, &page_buffer[addr], size);
91
92         return size;
93 }
94
95 static bool disk_page_load(struct BattFsSuper *d, pgcnt_t page)
96 {
97         //TRACEMSG("page:%d", page);
98         fseek(fp, page * d->page_size, SEEK_SET);
99         return fread(page_buffer, 1, d->page_size, fp) == d->page_size;
100 }
101
102 static bool disk_page_save(struct BattFsSuper *d, pgcnt_t page)
103 {
104         //TRACEMSG("page:%d", page);
105         fseek(fp, page * d->page_size, SEEK_SET);
106         return fwrite(page_buffer, 1, d->page_size, fp) == d->page_size;
107 }
108
109 static bool disk_page_erase(struct BattFsSuper *d, pgcnt_t page)
110 {
111         //TRACEMSG("page:%d", page);
112         fseek(fp, page * d->page_size, SEEK_SET);
113
114         for (int i = 0; i < d->page_size; i++)
115                 if (fputc(0xff, fp) == EOF)
116                         return false;
117         return true;
118 }
119
120 static bool disk_close(struct BattFsSuper *d)
121 {
122         //TRACE;
123         free(d->page_array);
124         return (fclose(fp) != EOF);
125 }
126
127 static void testCheck(BattFsSuper *disk, pgcnt_t *reference)
128 {
129         ASSERT(battfs_init(disk));
130
131         for (int i = 0; i < disk->page_count; i++)
132         {
133                 if (disk->page_array[i] != reference[i])
134                 {
135                         kprintf("Error at addr %d: page_array read", i);
136                         for (pgcnt_t i = 0; i < disk->page_count; i++)
137                         {
138                                 if (!(i % 16))
139                                         kputchar('\n');
140                                 kprintf("%04d ", disk->page_array[i]);
141                         }
142                         kputchar('\n');
143                         kprintf("Expected:");
144                         for (pgcnt_t i = 0; i < disk->page_count; i++)
145                         {
146                                 if (!(i % 16))
147                                         kputchar('\n');
148                                 kprintf("%04d ", reference[i]);
149                         }
150                         kputchar('\n');
151                         battfs_close(disk);
152                         exit(2);
153                 }
154         }
155         battfs_close(disk);
156 }
157
158 static void test1(BattFsSuper *disk)
159 {
160         pgcnt_t ref[PAGE_COUNT];
161         kprintf("Test1: disk new\n");
162
163         FILE *fpt = fopen(test_filename, "w+");
164
165         for (int i = 0; i < FILE_SIZE; i++)
166                 fputc(0xff, fpt);
167         fclose(fpt);
168         for (int i = 0; i < PAGE_COUNT; i++)
169                 ref[i] = i;
170
171         testCheck(disk, ref);
172         kprintf("Test1: passed\n");
173 }
174
175 static void test2(BattFsSuper *disk)
176 {
177         pgcnt_t ref[PAGE_COUNT];
178         kprintf("Test2: disk full with 1 contiguos file\n");
179
180
181         fp = fopen(test_filename, "w+");
182
183         for (int i = 0; i < PAGE_COUNT; i++)
184         {
185                 battfs_writeTestBlock(disk, i, 0, 0, 0, i);
186                 ref[i] = i;
187         }
188         fclose(fp);
189
190         testCheck(disk, ref);
191         kprintf("Test2: passed\n");
192 }
193
194
195 static void test3(BattFsSuper *disk)
196 {
197         pgcnt_t ref[PAGE_COUNT];
198         kprintf("Test3: disk half full with 1 contiguos file, rest unformatted\n");
199
200
201         fp = fopen(test_filename, "w+");
202
203         for (int i = 0; i < PAGE_COUNT / 2; i++)
204         {
205                 battfs_writeTestBlock(disk, i, 0, 0, 0, i);
206                 ref[i] = i;
207         }
208         fseek(fp, FILE_SIZE / 2, SEEK_SET);
209         for (int i = FILE_SIZE / 2; i < FILE_SIZE; i++)
210                 fputc(0xff, fp);
211         fclose(fp);
212
213         for (int i = PAGE_COUNT / 2; i < PAGE_COUNT; i++)
214         {
215                 ref[i] = i;
216         }
217
218
219         testCheck(disk, ref);
220         kprintf("Test3: passed\n");
221 }
222
223 #if 0
224 static void test4(BattFsSuper *disk)
225 {
226         pgcnt_t ref[PAGE_COUNT];
227         kprintf("Test4: disk half full with 1 contiguos file, rest marked free\n");
228
229
230         fp = fopen(test_filename, "w+");
231
232         for (int i = 0; i < PAGE_COUNT / 2; i++)
233         {
234                 battfs_writeTestBlock(disk, i, 0, 0, 0, i);
235                 ref[i] = i;
236         }
237         for (int i = PAGE_COUNT / 2; i < PAGE_COUNT; i++)
238         {
239                 battfs_writeTestBlock(disk, i, 0, 0, 0, i);
240                 ref[i] = i;
241         }
242         fclose(fp);
243
244
245         testCheck(disk, ref);
246         kprintf("Test4: passed\n");
247 }
248
249 static void test5(BattFsSuper *disk)
250 {
251         pgcnt_t ref[PAGE_COUNT];
252         kprintf("Test5: disk 1/3 full with 1 contiguos file, 1/3 marked free, rest unformatted\n");
253
254
255         fp = fopen(test_filename, "w+");
256
257         for (int i = 0; i < FILE_SIZE; i++)
258                 fputc(0xff, fp);
259
260         for (int i = 0; i < PAGE_COUNT / 3; i++)
261         {
262                 battfs_writeTestBlock(disk, i, 0, 0, 0, i);
263                 ref[i] = i;
264         }
265         for (int i = PAGE_COUNT / 3; i < 2 * (PAGE_COUNT / 3); i++)
266         {
267                 battfs_writeTestBlock(disk, i, 0, 0, 0, i);
268                 ref[i + PAGE_COUNT / 3 + 1] = i;
269         }
270         fclose(fp);
271
272         for (int i = PAGE_COUNT / 3; i < 2 * (PAGE_COUNT / 3) + 1; i++)
273                 ref[i] = PAGE_COUNT + PAGE_COUNT / 3 - i - 1;
274
275         testCheck(disk, ref);
276         kprintf("Test5: passed\n");
277 }
278 #endif
279
280 static void test6(BattFsSuper *disk)
281 {
282         pgcnt_t ref[4];
283         kprintf("Test6: 1 file with 1 old seq num, 1 free block\n");
284
285
286         fp = fopen(test_filename, "w+");
287         // page, inode, seq, fill, pgoff
288         battfs_writeTestBlock(disk, 0, 0, 0, 0, 0);
289         battfs_writeTestBlock(disk, 1, 0, 0, 0, 1);
290         battfs_writeTestBlock(disk, 2, 0, 1, 0, 1);
291         disk->erase(disk, 3);
292
293
294         fclose(fp);
295         ref[0] = 0;
296         ref[1] = 2;
297         ref[2] = 1;
298         ref[3] = 3;
299
300         testCheck(disk, ref);
301         kprintf("Test6: passed\n");
302 }
303
304 static void test7(BattFsSuper *disk)
305 {
306         pgcnt_t ref[4];
307         kprintf("Test7: 1 file with 1 old seq num, 1 free block\n");
308
309
310         fp = fopen(test_filename, "w+");
311         // page, inode, seq, fill, pgoff
312         battfs_writeTestBlock(disk, 0, 0, 0, 0, 0);
313         battfs_writeTestBlock(disk, 1, 0, 1, 0, 1);
314         battfs_writeTestBlock(disk, 2, 0, 0, 0, 1);
315         disk->erase(disk, 3);
316
317         fclose(fp);
318         ref[0] = 0;
319         ref[1] = 1;
320         ref[2] = 2;
321         ref[3] = 3;
322
323         testCheck(disk, ref);
324         kprintf("Test7: passed\n");
325 }
326
327 static void test8(BattFsSuper *disk)
328 {
329         pgcnt_t ref[4];
330         kprintf("Test8: 1 file with 1 old seq num, 1 free block\n");
331
332
333         fp = fopen(test_filename, "w+");
334
335         // page, inode, seq, fill, pgoff
336         disk->erase(disk, 0);
337         battfs_writeTestBlock(disk, 1, 0, 0, 0, 0);
338         battfs_writeTestBlock(disk, 2, 0, 1, 0, 1);
339         battfs_writeTestBlock(disk, 3, 0, 0, 0, 1);
340
341
342         fclose(fp);
343         ref[0] = 1;
344         ref[1] = 2;
345         ref[2] = 0;
346         ref[3] = 3;
347
348         testCheck(disk, ref);
349         kprintf("Test8: passed\n");
350 }
351
352 static void test9(BattFsSuper *disk)
353 {
354         pgcnt_t ref[8];
355         kprintf("Test9: 2 file with old seq num, 2 free block\n");
356
357
358         fp = fopen(test_filename, "w+");
359
360         // page, inode, seq, fill, pgoff
361         disk->erase(disk, 0);
362         battfs_writeTestBlock(disk, 1, 0, 0, 0, 0);
363         battfs_writeTestBlock(disk, 2, 0, 3, 0, 1);
364         battfs_writeTestBlock(disk, 3, 0, 0, 0, 1);
365         disk->erase(disk, 4);
366         battfs_writeTestBlock(disk, 5, 4, 0, 0, 0);
367         battfs_writeTestBlock(disk, 6, 4, 1, 0, 1);
368         battfs_writeTestBlock(disk, 7, 4, 0, 0, 1);
369
370
371         fclose(fp);
372         ref[0] = 1;
373         ref[1] = 2;
374         ref[2] = 5;
375         ref[3] = 6;
376         ref[4] = 0;
377         ref[5] = 3;
378         ref[6] = 4;
379         ref[7] = 7;
380
381         testCheck(disk, ref);
382         kprintf("Test9: passed\n");
383 }
384
385 static void test10(BattFsSuper *disk)
386 {
387         BattFs fd1;
388         BattFs fd2;
389         kprintf("Test10: open file test, inode 0 and inode 4\n");
390
391         fp = fopen(test_filename, "w+");
392
393         int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
394         unsigned int INODE = 0;
395         unsigned int INODE2 = 4;
396         unsigned int INEXISTENT_INODE = 123;
397         unsigned int MODE = 0;
398
399         // page, inode, seq, fill, pgoff
400         disk->erase(disk, 0);
401         battfs_writeTestBlock(disk, 1, INODE, 0, PAGE_FILL, 0);
402         battfs_writeTestBlock(disk, 2, INODE, 3, PAGE_FILL, 1);
403         battfs_writeTestBlock(disk, 3, INODE, 0, PAGE_FILL, 1);
404         disk->erase(disk, 4);
405         battfs_writeTestBlock(disk, 5, INODE2, 0, PAGE_FILL, 0);
406         battfs_writeTestBlock(disk, 6, INODE2, 1, PAGE_FILL, 1);
407         battfs_writeTestBlock(disk, 7, INODE2, 0, PAGE_FILL, 1);
408
409         fclose(fp);
410
411         ASSERT(battfs_init(disk));
412         ASSERT(!battfs_fileExists(disk, INEXISTENT_INODE));
413
414         ASSERT(battfs_fileExists(disk, INODE));
415         ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
416         ASSERT(fd1.fd.size == PAGE_FILL * 2);
417         ASSERT(fd1.fd.seek_pos == 0);
418         ASSERT(fd1.mode == MODE);
419         ASSERT(fd1.inode == INODE);
420         ASSERT(fd1.start == &disk->page_array[0]);
421         ASSERT(fd1.disk == disk);
422         ASSERT(LIST_HEAD(&disk->file_opened_list) == &fd1.link);
423
424         ASSERT(kfile_reopen(&fd1.fd) == &fd1.fd);
425         ASSERT(fd1.fd.size == PAGE_FILL * 2);
426         ASSERT(fd1.fd.seek_pos == 0);
427         ASSERT(fd1.mode == MODE);
428         ASSERT(fd1.inode == INODE);
429         ASSERT(fd1.start == &disk->page_array[0]);
430         ASSERT(fd1.disk == disk);
431         ASSERT(LIST_HEAD(&disk->file_opened_list) == &fd1.link);
432
433         ASSERT(battfs_fileExists(disk, INODE2));
434         ASSERT(battfs_fileopen(disk, &fd2, INODE2, MODE));
435         ASSERT(fd2.fd.size == PAGE_FILL * 2);
436         ASSERT(fd2.fd.seek_pos == 0);
437         ASSERT(fd2.mode == MODE);
438         ASSERT(fd2.inode == INODE2);
439         ASSERT(fd2.start == &disk->page_array[2]);
440         ASSERT(fd2.disk == disk);
441         ASSERT(LIST_HEAD(&disk->file_opened_list)->succ == &fd2.link);
442
443         ASSERT(kfile_close(&fd1.fd) == 0);
444         ASSERT(kfile_close(&fd2.fd) == 0);
445         ASSERT(LIST_EMPTY(&disk->file_opened_list));
446         ASSERT(battfs_close(disk));
447
448         kprintf("Test10: passed\n");
449 }
450
451 static void test11(BattFsSuper *disk)
452 {
453         BattFs fd1;
454         uint8_t buf[16];
455
456         kprintf("Test11: read file test\n");
457
458         fp = fopen(test_filename, "w+");
459
460         unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
461         unsigned int INODE = 0;
462         unsigned int INODE2 = 4;
463         unsigned int MODE = 0;
464
465         disk->erase(disk, 0);
466         battfs_writeTestBlock(disk, 1, INODE, 0, PAGE_FILL, 0);
467         battfs_writeTestBlock(disk, 2, INODE, 3, PAGE_FILL, 1);
468         battfs_writeTestBlock(disk, 3, INODE, 0, PAGE_FILL, 1);
469         disk->erase(disk, 4);
470         battfs_writeTestBlock(disk, 5, INODE2, 0, PAGE_FILL, 0);
471         battfs_writeTestBlock(disk, 6, INODE2, 1, PAGE_FILL, 1);
472         battfs_writeTestBlock(disk, 7, INODE2, 0, PAGE_FILL, 1);
473
474         fclose(fp);
475
476         ASSERT(battfs_init(disk));
477         ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
478         ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
479         ASSERT(fd1.fd.seek_pos == sizeof(buf));
480         for (size_t i = 0; i < sizeof(buf); i++)
481                 ASSERT(buf[i] == 0xff);
482
483         ASSERT(kfile_close(&fd1.fd) == 0);
484         ASSERT(battfs_close(disk));
485
486         kprintf("Test11: passed\n");
487 }
488
489 static void test12(BattFsSuper *disk)
490 {
491         BattFs fd1;
492
493         kprintf("Test12: read file test across page boundary and seek test\n");
494
495         fp = fopen(test_filename, "w+");
496
497         const unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
498         unsigned int INODE = 0;
499         unsigned int MODE = 0;
500         uint8_t buf[PAGE_FILL + BATTFS_HEADER_LEN / 2];
501
502         disk->erase(disk, 0);
503         battfs_writeTestBlock(disk, 1, INODE, 0, PAGE_FILL, 0);
504         battfs_writeTestBlock(disk, 2, INODE, 3, PAGE_FILL, 1);
505         battfs_writeTestBlock(disk, 3, INODE, 0, PAGE_FILL, 1);
506         disk->erase(disk, 4);
507         battfs_writeTestBlock(disk, 5, INODE, 0, PAGE_FILL, 2);
508         battfs_writeTestBlock(disk, 6, INODE, 1, PAGE_FILL, 3);
509         battfs_writeTestBlock(disk, 7, INODE, 0, PAGE_FILL, 3);
510
511         fclose(fp);
512
513         ASSERT(battfs_init(disk));
514         ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
515
516         ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
517         ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf));
518         for (size_t i = 0; i < sizeof(buf); i++)
519                 ASSERT(buf[i] == 0xff);
520
521         ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
522         ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 2);
523         for (size_t i = 0; i < sizeof(buf); i++)
524                 ASSERT(buf[i] == 0xff);
525
526         ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
527         ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 3);
528         for (size_t i = 0; i < sizeof(buf); i++)
529                 ASSERT(buf[i] == 0xff);
530
531         ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == PAGE_FILL * 4 - sizeof(buf) * 3);
532         ASSERT(fd1.fd.seek_pos == (kfile_off_t)fd1.fd.size);
533         for (size_t i = 0; i < PAGE_FILL * 4 - sizeof(buf) * 3; i++)
534                 ASSERT(buf[i] == 0xff);
535
536         ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
537         ASSERT(fd1.fd.seek_pos == 0);
538
539         ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_END) == (kfile_off_t)fd1.fd.size);
540         ASSERT(fd1.fd.seek_pos = (kfile_off_t)fd1.fd.size);
541
542         ASSERT(kfile_close(&fd1.fd) == 0);
543         ASSERT(battfs_close(disk));
544
545         kprintf("Test12: passed\n");
546 }
547
548
549 static void test13(BattFsSuper *disk)
550 {
551         BattFs fd1;
552         uint8_t buf[PAGE_SIZE - BATTFS_HEADER_LEN];
553
554         kprintf("Test13: write file test\n");
555
556         fp = fopen(test_filename, "w+");
557
558         unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
559         unsigned int INODE = 0;
560         unsigned int INODE2 = 4;
561         unsigned int MODE = 0;
562
563         disk->erase(disk, 0);
564         battfs_writeTestBlock(disk, 1, INODE, 0, PAGE_FILL, 0);
565         battfs_writeTestBlock(disk, 2, INODE, 3, PAGE_FILL, 1);
566         battfs_writeTestBlock(disk, 3, INODE, 0, PAGE_FILL, 1);
567         disk->erase(disk, 4);
568         battfs_writeTestBlock(disk, 5, INODE2, 0, PAGE_FILL, 0);
569         battfs_writeTestBlock(disk, 6, INODE2, 1, PAGE_FILL, 1);
570         battfs_writeTestBlock(disk, 7, INODE2, 0, PAGE_FILL, 1);
571
572         fclose(fp);
573
574         for (size_t i = 0; i < sizeof(buf); i++)
575                 buf[i] = i;
576
577         ASSERT(battfs_init(disk));
578         ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
579         ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
580         ASSERT(fd1.fd.seek_pos == sizeof(buf));
581         ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
582         ASSERT(fd1.fd.seek_pos == 0);
583
584         memset(buf, 0, sizeof(buf));
585         ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
586         for (size_t i = 0; i < sizeof(buf); i++)
587                 ASSERT(buf[i] == i);
588
589         ASSERT(kfile_close(&fd1.fd) == 0);
590         ASSERT(battfs_close(disk));
591
592         kprintf("Test13: passed\n");
593 }
594
595 static void test14(BattFsSuper *disk)
596 {
597         BattFs fd1;
598
599         kprintf("Test14: write file test across page boundary and seek test\n");
600
601         fp = fopen(test_filename, "w+");
602
603         const unsigned int PAGE_FILL = PAGE_SIZE - BATTFS_HEADER_LEN;
604         unsigned int INODE = 0;
605         unsigned int MODE = 0;
606         uint8_t buf[PAGE_FILL + BATTFS_HEADER_LEN / 2];
607
608         disk->erase(disk, 0);
609         battfs_writeTestBlock(disk, 1, INODE, 0, PAGE_FILL, 0);
610         battfs_writeTestBlock(disk, 2, INODE, 3, PAGE_FILL, 1);
611         battfs_writeTestBlock(disk, 3, INODE, 0, PAGE_FILL, 1);
612         disk->erase(disk, 4);
613         battfs_writeTestBlock(disk, 5, INODE, 0, PAGE_FILL, 2);
614         battfs_writeTestBlock(disk, 6, INODE, 1, PAGE_FILL, 3);
615         battfs_writeTestBlock(disk, 7, INODE, 0, PAGE_FILL, 3);
616
617         fclose(fp);
618
619         ASSERT(battfs_init(disk));
620         ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
621
622         uint8_t val = 0;
623         for (size_t i = 0; i < sizeof(buf); i++)
624                 buf[i] = val++;
625         ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
626         ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf));
627
628         for (size_t i = 0; i < sizeof(buf); i++)
629                 buf[i] = val++;
630         ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
631         ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 2);
632
633         for (size_t i = 0; i < sizeof(buf); i++)
634                 buf[i] = val++;
635         ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
636         ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 3);
637
638         ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
639         ASSERT(fd1.fd.seek_pos == 0);
640         val = 0;
641
642         memset(buf, 0, sizeof(buf));
643         ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
644         for (size_t i = 0; i < sizeof(buf); i++)
645                 ASSERT(buf[i] == val++);
646
647         memset(buf, 0, sizeof(buf));
648         ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
649         for (size_t i = 0; i < sizeof(buf); i++)
650                 ASSERT(buf[i] == val++);
651
652         memset(buf, 0, sizeof(buf));
653         ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
654         for (size_t i = 0; i < sizeof(buf); i++)
655                 ASSERT(buf[i] == val++);
656
657         ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 3);
658
659         ASSERT(kfile_close(&fd1.fd) == 0);
660         ASSERT(battfs_close(disk));
661
662         kprintf("Test14: passed\n");
663 }
664
665 static void test15(BattFsSuper *disk)
666 {
667         kprintf("Test15: file creation on new disk\n");
668
669         FILE *fpt = fopen(test_filename, "w+");
670
671         for (int i = 0; i < FILE_SIZE; i++)
672                 fputc(0xff, fpt);
673         fclose(fpt);
674
675         BattFs fd1;
676         unsigned int INODE = 0;
677         unsigned int MODE = BATTFS_CREATE;
678
679         ASSERT(battfs_init(disk));
680         ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
681         for (int i = 0; i < FILE_SIZE / 2; i++)
682                 ASSERT(kfile_putc(i, &fd1.fd) != EOF);
683
684         ASSERT(fd1.fd.seek_pos == FILE_SIZE / 2);
685         ASSERT(fd1.fd.size == FILE_SIZE / 2);
686         ASSERT(kfile_close(&fd1.fd) == 0);
687         ASSERT(battfs_close(disk));
688
689         ASSERT(battfs_init(disk));
690         ASSERT(battfs_fileopen(disk, &fd1, INODE, 0));
691         ASSERT(fd1.fd.size == FILE_SIZE / 2);
692         ASSERT(fd1.fd.seek_pos == 0);
693
694         uint8_t buf[FILE_SIZE / 2];
695         memset(buf, 0, sizeof(buf));
696         ASSERT(kfile_read(&fd1.fd, buf, FILE_SIZE / 2) == FILE_SIZE / 2);
697
698         for (int i = 0; i < FILE_SIZE / 2; i++)
699                 ASSERT(buf[i] == (i & 0xff));
700
701         ASSERT(fd1.fd.seek_pos == FILE_SIZE / 2);
702         ASSERT(kfile_close(&fd1.fd) == 0);
703         ASSERT(battfs_close(disk));
704
705
706         kprintf("Test15: passed\n");
707 }
708
709 static void test16(BattFsSuper *disk)
710 {
711         kprintf("Test16: multiple write on file\n");
712
713         FILE *fpt = fopen(test_filename, "w+");
714
715         for (int i = 0; i < FILE_SIZE; i++)
716                 fputc(0xff, fpt);
717         fclose(fpt);
718
719         BattFs fd1;
720         unsigned int INODE = 0;
721         unsigned int MODE = BATTFS_CREATE;
722         uint8_t buf[1000];
723
724         ASSERT(battfs_init(disk));
725         ASSERT(battfs_fileopen(disk, &fd1, INODE, MODE));
726
727         int j;
728         for (j = 1; j < 1013; j++)
729         {
730                 for (int i = 0; i < sizeof(buf); i++)
731                         buf[i] = j+i;
732
733                 ASSERT(kfile_write(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
734                 ASSERT(fd1.fd.seek_pos == sizeof(buf));
735                 ASSERT(fd1.fd.size == sizeof(buf));
736                 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
737                 memset(buf, 0, sizeof(buf));
738                 ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
739                 ASSERT(fd1.fd.seek_pos == sizeof(buf));
740                 for (int i = 0; i < sizeof(buf); i++)
741                         ASSERT(buf[i] == ((j+i) & 0xff));
742                 ASSERT(kfile_seek(&fd1.fd, 0, KSM_SEEK_SET) == 0);
743                 ASSERT(disk->free_bytes == disk->disk_size - sizeof(buf));
744         }
745         ASSERT(kfile_close(&fd1.fd) == 0);
746         ASSERT(battfs_close(disk));
747
748         ASSERT(battfs_init(disk));
749         ASSERT(disk->free_bytes == disk->disk_size - sizeof(buf));
750         ASSERT(battfs_fileopen(disk, &fd1, INODE, 0));
751         ASSERT(fd1.fd.size == sizeof(buf));
752         memset(buf, 0, sizeof(buf));
753         ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == sizeof(buf));
754         for (int i = 0; i < sizeof(buf); i++)
755                         ASSERT(buf[i] == ((j-1+i) & 0xff));
756         ASSERT(kfile_close(&fd1.fd) == 0);
757         ASSERT(battfs_close(disk));
758
759
760         kprintf("Test16: passed\n");
761 }
762
763 static void test17(BattFsSuper *disk)
764 {
765         kprintf("Test17: increasing dimension of a file with multiple open files.\n");
766
767         FILE *fpt = fopen(test_filename, "w+");
768
769         for (int i = 0; i < FILE_SIZE / 10; i++)
770                 fputc(0xff, fpt);
771         fclose(fpt);
772
773         BattFs fd1,fd2;
774         unsigned int INODE1 = 1, INODE2 = 2;
775         unsigned int MODE = BATTFS_CREATE;
776         uint8_t buf[1000];
777
778         ASSERT(battfs_init(disk));
779         ASSERT(battfs_fileopen(disk, &fd1, INODE1, MODE));
780         ASSERT(battfs_fileopen(disk, &fd2, INODE2, MODE));
781         for (int i = 0; i < sizeof(buf); i++)
782                 ASSERT(kfile_putc(i, &fd2.fd) != EOF);
783         ASSERT(kfile_seek(&fd2.fd, 0, KSM_SEEK_SET) == 0);
784         memset(buf, 0, sizeof(buf));
785         ASSERT(kfile_read(&fd2.fd, buf, sizeof(buf)) == sizeof(buf));
786
787         for (int i = 0; i < sizeof(buf); i++)
788                 ASSERT(buf[i] == (i & 0xff));
789         ASSERT(kfile_seek(&fd2.fd, 0, KSM_SEEK_SET) == 0);
790
791         for (int i = 0; i < sizeof(buf); i++)
792                 ASSERT(kfile_putc(i, &fd1.fd) != EOF);
793
794         memset(buf, 0, sizeof(buf));
795         ASSERT(kfile_read(&fd2.fd, buf, sizeof(buf)) == sizeof(buf));
796
797         for (int i = 0; i < sizeof(buf); i++)
798                 ASSERT(buf[i] == (i & 0xff));
799
800         ASSERT(kfile_close(&fd1.fd) == 0);
801         ASSERT(kfile_close(&fd2.fd) == 0);
802         ASSERT(battfs_close(disk));
803
804         kprintf("Test17: passed\n");
805 }
806
807 int battfs_testRun(void)
808 {
809         BattFsSuper disk;
810
811         disk.open = disk_open;
812         disk.read = disk_page_read;
813         disk.load = disk_page_load;
814         disk.bufferWrite = disk_buffer_write;
815         disk.bufferRead = disk_buffer_read;
816         disk.save = disk_page_save;
817         disk.erase = disk_page_erase;
818         disk.close = disk_close;
819
820         test1(&disk);
821         test2(&disk);
822         test3(&disk);
823         //test4(&disk);
824         //test5(&disk);
825         test6(&disk);
826         test7(&disk);
827         test8(&disk);
828         test9(&disk);
829         test10(&disk);
830         test11(&disk);
831         test12(&disk);
832         test13(&disk);
833         test14(&disk);
834         test15(&disk);
835         test16(&disk);
836         test17(&disk);
837         kprintf("All tests passed!\n");
838
839         return 0;
840 }
841
842 int battfs_testSetup(void)
843 {
844         return 0;
845 }
846
847 int battfs_testTearDown(void)
848 {
849         return 0;
850 }
851
852 TEST_MAIN(battfs)
853
854 #include <fs/battfs.c>
855 #include <kern/kfile.c>
856 #include <drv/kdebug.c>
857 #include <mware/formatwr.c>
858 #include <mware/hex.c>
859
860 #endif // _TEST