altos: Stick a mutex around FAT operations
[fw/altos] / src / test / ao_fat_test.c
index 48d5d8a43401100e7871e7991de9d7b387857df5..d1309024063270a99f3ac6ec507236e1c00bed4f 100644 (file)
@@ -158,14 +158,14 @@ ao_fat_entry_raw_read(cluster_t cluster, uint8_t fat)
                cluster <<= 1;
        sector = cluster >> SECTOR_SHIFT;
        offset = cluster & SECTOR_MASK;
-       buf = ao_fat_sector_get(fat_start + fat * sectors_per_fat + sector);
+       buf = _ao_fat_sector_get(fat_start + fat * sectors_per_fat + sector);
        if (!buf)
                return 0;
        if (fat32)
                ret = get_u32(buf + offset);
        else
                ret = get_u16(buf + offset);
-       ao_fat_sector_put(buf, 0);
+       _ao_fat_sector_put(buf, 0);
        return ret;
 }
 
@@ -226,14 +226,15 @@ fatal(char *msg, ...)
 void
 check_fat(void)
 {
-       int     e;
-       int     f;
+       cluster_t       e;
+       int             f;
 
        for (e = 0; e < number_cluster; e++) {
                cluster_t       v = ao_fat_entry_raw_read(e, 0);
                for (f = 1; f < number_fat; f++) {
-                       if (ao_fat_entry_raw_read(e, f) != v)
-                               fatal ("fats differ at %d\n", e);
+                       cluster_t       o = ao_fat_entry_raw_read(e, f);
+                       if (o != v)
+                               fatal ("fats differ at %08x (0 %08x %d %08x)\n", e, v, f, o);
                }
        }
 }
@@ -251,7 +252,7 @@ check_file(dirent_t dent, cluster_t first_cluster, dirent_t *used)
             fat32 ? !AO_FAT_IS_LAST_CLUSTER(cluster) : !AO_FAT_IS_LAST_CLUSTER16(cluster);
             cluster = ao_fat_entry_raw_read(cluster, 0))
        {
-               if (!ao_fat_cluster_valid(cluster))
+               if (!_ao_fat_cluster_valid(cluster))
                        fatal("file %d: invalid cluster %08x\n", dent, cluster);
                if (used[cluster])
                        fatal("file %d: duplicate cluster %08x also in file %d\n", dent, cluster, used[cluster]-1);
@@ -273,7 +274,7 @@ check_fs(void)
 
        used = calloc(sizeof (dirent_t), number_cluster);
 
-       for (r = 0; (dent = ao_fat_root_get(r)); r++) {
+       for (r = 0; (dent = _ao_fat_root_get(r)); r++) {
                cluster_t       clusters;
                offset_t        size;
                cluster_t       first_cluster;
@@ -286,7 +287,7 @@ check_fs(void)
                if (fat32)
                        first_cluster |= (cluster_t) get_u16(dent + 0x14) << 16;
                size = get_u32(dent + 0x1c);
-               ao_fat_root_put(dent, r, 0);
+               _ao_fat_root_put(dent, r, 0);
 
                if (name[0] == AO_FAT_DENT_END) {
                        break;
@@ -307,12 +308,12 @@ check_fs(void)
        }
        if (!fat32) {
                for (; r < root_entries; r++) {
-                       uint8_t *dent = ao_fat_root_get(r);
+                       uint8_t *dent = _ao_fat_root_get(r);
                        if (!dent)
                                fatal("cannot map dent %d\n", r);
                        if (dent[0] != AO_FAT_DENT_END)
                                fatal("found non-zero dent past end %d\n", r);
-                       ao_fat_root_put(dent, r, 0);
+                       _ao_fat_root_put(dent, r, 0);
                }
        } else {
                check_file((dirent_t) -1, root_cluster, used);
@@ -349,28 +350,89 @@ uint32_t          sizes[NUM_FILES];
 
 unsigned char          md5[NUM_FILES][MD5_DIGEST_LENGTH];
 
+void
+micro_test_fs(void)
+{
+       int8_t  fd;
+       char    name[] = "FOO        ";
+       char    buf[512];
+       int     len;
+
+       printf ("write once\n");
+       if ((fd = ao_fat_creat(name)) >= 0) {
+               ao_fat_write(fd, "hello world\n", 12);
+               ao_fat_close(fd);
+       }
+
+       printf ("read first\n");
+       if ((fd = ao_fat_open(name, AO_FAT_OPEN_READ)) >= 0) {
+               len = ao_fat_read(fd, buf, sizeof(buf));
+               write (1, buf, len);
+               ao_fat_close(fd);
+       }
+       
+       printf ("write again\n");
+       if ((fd = ao_fat_creat(name)) >= 0) {
+               ao_fat_write(fd, "hi\n", 3);
+               ao_fat_close(fd);
+       }
+
+       printf ("read again\n");
+       if ((fd = ao_fat_open(name, AO_FAT_OPEN_READ)) >= 0) {
+               len = ao_fat_read(fd, buf, sizeof(buf));
+               write (1, buf, len);
+               ao_fat_close(fd);
+       }
+
+       printf ("write 3\n");
+       if ((fd = ao_fat_creat(name)) >= 0) {
+               int     l;
+               char    c;
+
+               for (l = 0; l < 10; l++) {
+                       for (c = ' '; c < '~'; c++)
+                               ao_fat_write(fd, &c, 1);
+                       c = '\n';
+                       ao_fat_write(fd, &c, 1);
+               }
+               ao_fat_close(fd);
+       }
+
+       printf ("read 3\n");
+       if ((fd = ao_fat_open(name, AO_FAT_OPEN_READ)) >= 0) {
+               while ((len = ao_fat_read(fd, buf, sizeof(buf))) > 0)
+                       write (1, buf, len);
+               ao_fat_close(fd);
+       }
+
+       check_fs();
+       printf ("all done\n");
+}
+
+
 void
 short_test_fs(void)
 {
        int     len;
+       int8_t  fd;
        char    buf[345];
 
-       if (ao_fat_open("HELLO   TXT",AO_FAT_OPEN_READ) == AO_FAT_SUCCESS) {
+       if ((fd = ao_fat_open("HELLO   TXT",AO_FAT_OPEN_READ)) >= 0) {
                printf ("File contents for HELLO.TXT\n");
-               while ((len = ao_fat_read(buf, sizeof(buf))))
+               while ((len = ao_fat_read(fd, buf, sizeof(buf))))
                        write(1, buf, len);
-               ao_fat_close();
+               ao_fat_close(fd);
        }
        
-       if (ao_fat_creat("NEWFILE TXT") == AO_FAT_SUCCESS) {
+       if ((fd = ao_fat_creat("NEWFILE TXT")) >= 0) {
                printf ("Create new file\n");
                for (len = 0; len < 2; len++)
-                       ao_fat_write("hello, world!\n", 14);
-               ao_fat_seek(0, AO_FAT_SEEK_SET);
+                       ao_fat_write(fd, "hello, world!\n", 14);
+               ao_fat_seek(fd, 0, AO_FAT_SEEK_SET);
                printf ("read new file\n");
-               while ((len = ao_fat_read(buf, sizeof (buf))))
+               while ((len = ao_fat_read(fd, buf, sizeof (buf))))
                        write (1, buf, len);
-               ao_fat_close();
+               ao_fat_close(fd);
        }
 
        check_fs();
@@ -385,6 +447,7 @@ long_test_fs(void)
        unsigned char   md5_check[MD5_DIGEST_LENGTH];
        char buf[337];
        int     len;
+       int8_t  fd;
        uint64_t        total_file_size = 0;
 
        total_reads = total_writes = 0;
@@ -394,10 +457,10 @@ long_test_fs(void)
        memset(sizes, '\0', sizeof (sizes));
        for (id = 0; id < NUM_FILES; id++) {
                sprintf(name, "D%07dTXT", id);
-               if ((id % (NUM_FILES/50)) == 0) {
+               if ((id % ((NUM_FILES+49)/50)) == 0) {
                        printf ("."); fflush(stdout);
                }
-               if (ao_fat_creat(name) == AO_FAT_SUCCESS) {
+               if ((fd = ao_fat_creat(name)) >= 0) {
                        int j;
                        char    line[64];
                        check_bufio("file created");
@@ -406,7 +469,7 @@ long_test_fs(void)
                                int len, ret;
                                sprintf (line, "Hello, world %d %d\r\n", id, j);
                                len = strlen(line);
-                               ret = ao_fat_write((uint8_t *) line, len);
+                               ret = ao_fat_write(fd, line, len);
                                if (ret <= 0)
                                        break;
                                total_file_size += ret;
@@ -415,7 +478,7 @@ long_test_fs(void)
                                if (ret != len)
                                        printf ("write failed %d\n", ret);
                        }
-                       ao_fat_close();
+                       ao_fat_close(fd);
                        MD5_Final(&md5[id][0], &ctx);
                        check_bufio("file written");
                }
@@ -435,16 +498,16 @@ long_test_fs(void)
                uint32_t size;
                sprintf(name, "D%07dTXT", id);
                size = 0;
-               if ((id % (NUM_FILES/50)) == 0) {
+               if ((id % ((NUM_FILES+49)/50)) == 0) {
                        printf ("."); fflush(stdout);
                }
-               if (ao_fat_open(name, AO_FAT_OPEN_READ) == AO_FAT_SUCCESS) {
+               if ((fd = ao_fat_open(name, AO_FAT_OPEN_READ)) >= 0) {
                        MD5_Init(&ctx);
-                       while ((len = ao_fat_read((uint8_t *) buf, sizeof(buf))) > 0) {
+                       while ((len = ao_fat_read(fd, buf, sizeof(buf))) > 0) {
                                MD5_Update(&ctx, buf, len);
                                size += len;
                        }
-                       ao_fat_close();
+                       ao_fat_close(fd);
                        MD5_Final(md5_check, &ctx);
                        if (size != sizes[id])
                                fatal("file %d: size differs %d written %d read\n",
@@ -467,6 +530,20 @@ char *params[] = {
        NULL
 };
 
+void
+do_test(void (*test)(void))
+{
+       ao_fat_init();
+
+       check_bufio("top");
+       _ao_fat_setup();
+
+       check_fs();
+       check_bufio("after setup");
+       (*test)();
+       ao_fat_unmount();
+}
+
 int
 main(int argc, char **argv)
 {
@@ -477,20 +554,12 @@ main(int argc, char **argv)
 
        for (p = 0; fs_params[p].fat; p++) {
                param = &fs_params[p];
-               ao_fat_init();
-
-               check_bufio("top");
-               ao_fat_setup();
-
-               check_fs();
-               check_bufio("after setup");
 
-#ifdef SIMPLE_TEST
-               short_test_fs();
-#else
-               long_test_fs();
-#endif
+               do_test(micro_test_fs);
+               do_test(short_test_fs);
+               do_test(long_test_fs);
        }
+       unlink (fs);
 
        return 0;
 }