Refactor test; add more tests.
[bertos.git] / app / battfs / 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 Develer S.r.l. (http://www.develer.com/)
30  *
31  * -->
32  *
33  * \version $Id: demo.c 18242 2007-10-08 17:35:23Z marco $
34  *
35  * \author Francesco Sacchi <batt@develer.com>
36  *
37  * \brief BattFs Test.
38  */
39
40 #include <cfg/debug.h>
41 #include <fs/battfs.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 FILE *fp;
52 const char test_filename[]="battfs_disk.bin";
53
54
55 static bool disk_open(struct BattFsSuper *d)
56 {
57         fp = fopen(test_filename, "r+b");
58         ASSERT(fp);
59         fseek(fp, 0, SEEK_END);
60         d->page_size = PAGE_SIZE;
61         d->page_count = ftell(fp) / d->page_size;
62         d->page_array = malloc(d->page_count * sizeof(pgcnt_t));
63         //TRACEMSG("page_size:%d, page_count:%d\n", d->page_size, d->page_count);
64         return (fp && d->page_array);
65 }
66
67 static size_t disk_page_read(struct BattFsSuper *d, pgcnt_t page, pgaddr_t addr, void *buf, size_t size)
68 {
69         //TRACEMSG("page:%d, addr:%d, size:%d\n", page, addr, size);
70         fseek(fp, page * d->page_size + addr, SEEK_SET);
71         return fread(buf, 1, size, fp);
72 }
73
74 static size_t disk_page_write(struct BattFsSuper *d, pgcnt_t page, pgaddr_t addr, const void *buf, size_t size)
75 {
76         //TRACEMSG("page:%d, addr:%d, size:%d\n", page, addr, size);
77         fseek(fp, page * d->page_size + addr, SEEK_SET);
78         return fwrite(buf, 1, size, fp);
79 }
80
81 static bool disk_page_erase(struct BattFsSuper *d, pgcnt_t page)
82 {
83         //TRACEMSG("page:%d\n", page);
84         fseek(fp, page * d->page_size, SEEK_SET);
85
86         for (int i = 0; i < d->page_size; i++)
87                 if (fputc(0xff, fp) == EOF)
88                         return false;
89         return true;
90 }
91
92 static bool disk_close(struct BattFsSuper *d)
93 {
94         //TRACE;
95         free(d->page_array);
96         return (fclose(fp) != EOF);
97 }
98
99 static void testCheck(BattFsSuper *disk, pgcnt_t *reference)
100 {
101         if (battfs_init(disk))
102         {
103                 for (int i = 0; i < disk->page_count; i++)
104                 {
105                         if (disk->page_array[i] != reference[i])
106                         {
107                                 kprintf("Error at addr %d: page_array read", i);
108                                 for (pgcnt_t i = 0; i < disk->page_count; i++)
109                                 {
110                                         if (!(i % 16))
111                                                 kputchar('\n');
112                                         kprintf("%04d ", disk->page_array[i]);
113                                 }
114                                 kputchar('\n');
115                                 kprintf("Expected:");
116                                 for (pgcnt_t i = 0; i < disk->page_count; i++)
117                                 {
118                                         if (!(i % 16))
119                                                 kputchar('\n');
120                                         kprintf("%04d ", reference[i]);
121                                 }
122                                 kputchar('\n');
123                                 battfs_close(disk);
124                                 exit(2);
125                         }
126                 }
127                 battfs_close(disk);
128         }
129         else
130         {
131                 kprintf("Error in battfs_init\n");
132                 exit(1);
133         }
134 }
135
136 static void test1(BattFsSuper *disk)
137 {
138         pgcnt_t ref[PAGE_COUNT];
139         kprintf("Test1: disk new\n");
140
141         FILE *fpt = fopen(test_filename, "w+");
142
143         for (int i = 0; i < FILE_SIZE; i++)
144                 fputc(0xff, fpt);
145         fclose(fpt);
146         for (int i = 0; i < PAGE_COUNT; i++)
147                 ref[i] = PAGE_COUNT - i - 1;
148
149         testCheck(disk, ref);
150         kprintf("Test1: passed\n");
151 }
152
153 static void test2(BattFsSuper *disk)
154 {
155         pgcnt_t ref[PAGE_COUNT];
156         kprintf("Test2: disk full with 1 contiguos file\n");
157
158
159         fp = fopen(test_filename, "w+");
160
161         for (int i = 0; i < PAGE_COUNT; i++)
162         {
163                 battfs_writeTestBlock(disk, i, 0, 0, 0, i, MARK_PAGE_VALID);
164                 ref[i] = i;
165         }
166         fclose(fp);
167
168         testCheck(disk, ref);
169         kprintf("Test2: passed\n");
170 }
171
172
173 static void test3(BattFsSuper *disk)
174 {
175         pgcnt_t ref[PAGE_COUNT];
176         kprintf("Test3: disk half full with 1 contiguos file, rest unformatted\n");
177
178
179         fp = fopen(test_filename, "w+");
180
181         for (int i = 0; i < PAGE_COUNT / 2; i++)
182         {
183                 battfs_writeTestBlock(disk, i, 0, 0, 0, i, MARK_PAGE_VALID);
184                 ref[i] = i;
185         }
186         fseek(fp, FILE_SIZE / 2, SEEK_SET);
187         for (int i = FILE_SIZE / 2; i < FILE_SIZE; i++)
188                 fputc(0xff, fp);
189         fclose(fp);
190
191         for (int i = PAGE_COUNT / 2; i < PAGE_COUNT; i++)
192         {
193                 ref[i] = PAGE_COUNT + PAGE_COUNT / 2 - i - 1;
194         }
195
196
197         testCheck(disk, ref);
198         kprintf("Test3: passed\n");
199 }
200
201 static void test4(BattFsSuper *disk)
202 {
203         pgcnt_t ref[PAGE_COUNT];
204         kprintf("Test4: disk half full with 1 contiguos file, rest marked free\n");
205
206
207         fp = fopen(test_filename, "w+");
208
209         for (int i = 0; i < PAGE_COUNT / 2; i++)
210         {
211                 battfs_writeTestBlock(disk, i, 0, 0, 0, i, MARK_PAGE_VALID);
212                 ref[i] = i;
213         }
214         for (int i = PAGE_COUNT / 2; i < PAGE_COUNT; i++)
215         {
216                 battfs_writeTestBlock(disk, i, 0, 0, 0, i, i);
217                 ref[i] = i;
218         }
219         fclose(fp);
220
221
222         testCheck(disk, ref);
223         kprintf("Test4: passed\n");
224 }
225
226 static void test5(BattFsSuper *disk)
227 {
228         pgcnt_t ref[PAGE_COUNT];
229         kprintf("Test5: disk 1/3 full with 1 contiguos file, 1/3 marked free, rest unformatted\n");
230
231
232         fp = fopen(test_filename, "w+");
233
234         for (int i = 0; i < FILE_SIZE; i++)
235                 fputc(0xff, fp);
236
237         for (int i = 0; i < PAGE_COUNT / 3; i++)
238         {
239                 battfs_writeTestBlock(disk, i, 0, 0, 0, i, MARK_PAGE_VALID);
240                 ref[i] = i;
241         }
242         for (int i = PAGE_COUNT / 3; i < 2 * (PAGE_COUNT / 3); i++)
243         {
244                 battfs_writeTestBlock(disk, i, 0, 0, 0, i, i);
245                 ref[i + PAGE_COUNT / 3 + 1] = i;
246         }
247         fclose(fp);
248
249         for (int i = PAGE_COUNT / 3; i < 2 * (PAGE_COUNT / 3) + 1; i++)
250                 ref[i] = PAGE_COUNT + PAGE_COUNT / 3 - i - 1;
251
252         testCheck(disk, ref);
253         kprintf("Test5: passed\n");
254 }
255
256 static void test6(BattFsSuper *disk)
257 {
258         pgcnt_t ref[4];
259         kprintf("Test6: 1 file with 1 old seq num, 1 free block\n");
260
261
262         fp = fopen(test_filename, "w+");
263
264         battfs_writeTestBlock(disk, 0, 0, 0, 0, 0, MARK_PAGE_VALID);
265         battfs_writeTestBlock(disk, 1, 0, 0, 0, 1, MARK_PAGE_VALID);
266         battfs_writeTestBlock(disk, 2, 0, 1, 0, 1, MARK_PAGE_VALID);
267         battfs_writeTestBlock(disk, 3, 0, 0, 0, 0, 123);
268
269         fclose(fp);
270         ref[0] = 0;
271         ref[1] = 2;
272         ref[2] = 3;
273         ref[3] = 1;
274
275         testCheck(disk, ref);
276         kprintf("Test6: passed\n");
277 }
278
279 static void test7(BattFsSuper *disk)
280 {
281         pgcnt_t ref[4];
282         kprintf("Test7: 1 file with 1 old seq num, 1 free block\n");
283
284
285         fp = fopen(test_filename, "w+");
286
287         battfs_writeTestBlock(disk, 0, 0, 0, 0, 0, MARK_PAGE_VALID);
288         battfs_writeTestBlock(disk, 1, 0, 1, 0, 1, MARK_PAGE_VALID);
289         battfs_writeTestBlock(disk, 2, 0, 0, 0, 1, MARK_PAGE_VALID);
290         battfs_writeTestBlock(disk, 3, 0, 0, 0, 0, 123);
291
292         fclose(fp);
293         ref[0] = 0;
294         ref[1] = 1;
295         ref[2] = 3;
296         ref[3] = 2;
297
298         testCheck(disk, ref);
299         kprintf("Test7: passed\n");
300 }
301
302 static void test8(BattFsSuper *disk)
303 {
304         pgcnt_t ref[4];
305         kprintf("Test8: 1 file with 1 old seq num, 1 free block\n");
306
307
308         fp = fopen(test_filename, "w+");
309
310         battfs_writeTestBlock(disk, 0, 0, 0, 0, 0, 1235);
311         battfs_writeTestBlock(disk, 1, 0, 0, 0, 0, MARK_PAGE_VALID);
312         battfs_writeTestBlock(disk, 2, 0, 1, 0, 1, MARK_PAGE_VALID);
313         battfs_writeTestBlock(disk, 3, 0, 0, 0, 1, MARK_PAGE_VALID);
314
315
316         fclose(fp);
317         ref[0] = 1;
318         ref[1] = 2;
319         ref[2] = 0;
320         ref[3] = 3;
321
322         testCheck(disk, ref);
323         kprintf("Test8: passed\n");
324 }
325
326 static void test9(BattFsSuper *disk)
327 {
328         pgcnt_t ref[8];
329         kprintf("Test9: 2 file with old seq num, 2 free block\n");
330
331
332         fp = fopen(test_filename, "w+");
333
334         battfs_writeTestBlock(disk, 0, 0, 0, 0, 0, 1235);
335         battfs_writeTestBlock(disk, 1, 0, 0, 0, 0, MARK_PAGE_VALID);
336         battfs_writeTestBlock(disk, 2, 0, 3, 0, 1, MARK_PAGE_VALID);
337         battfs_writeTestBlock(disk, 3, 0, 0, 0, 1, MARK_PAGE_VALID);
338         battfs_writeTestBlock(disk, 4, 0, 0, 0, 0, 1236);
339         battfs_writeTestBlock(disk, 5, 4, 0, 0, 0, MARK_PAGE_VALID);
340         battfs_writeTestBlock(disk, 6, 4, 1, 0, 1, MARK_PAGE_VALID);
341         battfs_writeTestBlock(disk, 7, 4, 0, 0, 1, MARK_PAGE_VALID);
342
343
344         fclose(fp);
345         ref[0] = 1;
346         ref[1] = 3;
347         ref[2] = 5;
348         ref[3] = 6;
349         ref[4] = 0;
350         ref[5] = 4;
351         ref[6] = 2;
352         ref[7] = 7;
353
354         testCheck(disk, ref);
355         kprintf("Test9: passed\n");
356 }
357
358
359
360
361 int main(void)
362 {
363         BattFsSuper disk;
364
365         disk.open = disk_open;
366         disk.read = disk_page_read;
367         disk.write = disk_page_write;
368         disk.erase = disk_page_erase;
369         disk.close = disk_close;
370         test1(&disk);
371         test2(&disk);
372         test3(&disk);
373         test4(&disk);
374         test5(&disk);
375         test6(&disk);
376         test7(&disk);
377         test8(&disk);
378         test9(&disk);
379         kprintf("All test passed!\n");
380
381         return 0;
382 }