chiark / gitweb /
Test correct behaviour with corrupt superblock.
authorDan Sheppard <dan.sheppard.circle@gmail.com>
Tue, 22 Apr 2025 22:52:30 +0000 (23:52 +0100)
committerDan Sheppard <dan.sheppard.circle@gmail.com>
Tue, 22 Apr 2025 22:52:30 +0000 (23:52 +0100)
Makefile
src/superblock.c

index a5b373f04ce1df7509afe7e578dd0e18995293fb..71a574d730e23d8f1f737b740df5f2b7f91c1590 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ LIBS =
 CC = gcc
 CFLAGS = -Wall --std=c99
 MAINCFLAGS = -O3
-TESTCFLAGS = -g
+TESTCFLAGS = -O3 # or -g
 
 .PHONY: default all clean test
 
index c92489d42d3c5218fa7aeaf7e25f10e4ec3d17b3..f84b03c412ddc048c0573549f5abef3f29b1ce58 100644 (file)
@@ -260,7 +260,7 @@ static void test_close(coquet_t *cq) {
     test_bail(cq,r);
 }
 
-void test_superblock() {
+void test_superblock_main() {
     coquet_t cq;
     int i,r;
     struct cq_super super;
@@ -340,11 +340,8 @@ void test_superblock() {
 
     cq_super_save(&cq,&super,1);
 
-    r = (cq.vfs_funcs.close)(cq.vfs_data,COQUET_FILE_MAIN);
-    test_bail(&cq,r);
-
-    r = (cq.vfs_funcs.open)(cq.vfs_data,COQUET_FILE_MAIN,COQUET_CMODE_EITHER);
-    test_bail(&cq,r);
+    test_close(&cq);
+    test_open(&cq);
 
     r = cq_super_load(&cq,&super,1);
     test_bail(&cq,r);
@@ -363,10 +360,80 @@ void test_superblock() {
     test_bail(&cq,r);
 }
 
+static void make_superblock(coquet_t *cq, bool_t also_b, 
+                            int corrupt, int check) {
+    int r;
+    struct cq_super super;
+    uint8_t d;
+
+    test_unlink("tmp/test.coquet");
+
+    test_open(cq);
+    r = cq_super_load(cq,&super,1);
+    super.current.nursery_size = 12;
+    cq_super_save(cq,&super,1);
+    if(also_b) {
+        super.current.nursery_size = 11;
+        cq_super_save(cq,&super,1);
+    }
+    if(corrupt>-1) {
+        r = (cq->vfs_funcs.read)(cq->vfs_data,COQUET_FILE_MAIN,&d,corrupt,1);
+        test_bail(cq,r);
+        d += 1;
+        r = (cq->vfs_funcs.write)(cq->vfs_data,COQUET_FILE_MAIN,&d,corrupt,1);
+        test_bail(cq,r);
+    }
+    test_close(cq);
+
+    /* check */
+    test_open(cq);
+    r = cq_super_load(cq,&super,1);
+    test_bail(cq,r);
+    test_eq_int(super.current.nursery_size,check,"c1");
+    test_close(cq);
+}
+
+void test_superblock_corruption() {
+    coquet_t cq;
+    int i,r,pos;
+
+    r = coquet_init(&cq,"tmp/test");
+    test_bail(&cq,r);
+    testvfs_fakerandom(cq.vfs_data,0xA5);
+
+    test_unlink("tmp/test.coquet");
+
+    /* Not corrupting should lead to A, ie n.s. = 12 */
+    make_superblock(&cq,0,-1,12);
+
+    /* Corrupting A should lead us to default, ie n.s. = 10 */
+    for(i=0;i<200;i++) {
+        pos = i<100 ?i : 100+i*9;
+        make_superblock(&cq,0,pos,10);
+    }
+
+    /* Corrupting A should keep B, ie n.s. = 11 */
+    for(i=0;i<200;i++) {
+        pos = i<100 ?i : 100+i*9;
+        make_superblock(&cq,1,pos,11);
+    }
+
+    /* Corrupting B should give A, ie n.s. = 12 */
+    for(i=0;i<200;i++) {
+        pos = i<100 ?i : 100+i*9;
+        make_superblock(&cq,1,2048+pos,12);
+    }
+}
+
+void test_superblock() {
+    test_superblock_main();
+    test_superblock_corruption();
+}
+
 /* To test:
 
+move tests to external drive to avoid wear
 creation
-corruption
 a/b choice
 magic