From: Dan Sheppard Date: Tue, 22 Apr 2025 17:16:12 +0000 (+0100) Subject: Basic superblock test. X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~dans/git?a=commitdiff_plain;h=51266b3948cfc873f41d7b1c1e2c04c7f7f284cc;p=coquet.git Basic superblock test. --- diff --git a/.gitignore b/.gitignore index 497c041..2b5e1ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ *.o -*.coquet* +tmp/* a.out obj/* bin/* diff --git a/Makefile b/Makefile index 9f57f48..a5b373f 100644 --- a/Makefile +++ b/Makefile @@ -6,43 +6,50 @@ TESTOBJDIR := obj/test SRCFILES := unix.c util.c coquet.c superblock.c sha2.c testvfs.c SRC := $(addprefix $(SRCDIR)/,$(SRCFILES)) -DEPSRC := $(wildcard $(SRCDIR)/*.c) -DEPS = $(DEPSRC:$(SRCDIR)/%.c=$(OBJDIR)/%.d) -OBJ := $(SRC:$(SRCDIR)/%.c=$(OBJDIR)/%.o) +CLISRC := $(SRC) $(SRCDIR)/main.c +TESTSRC := $(SRC) $(SRCDIR)/test.c -TESTDEPS = $(DEPSRC:$(SRCDIR)/%.c=$(TESTOBJDIR)/%.d) -TESTOBJ := $(SRC:$(SRCDIR)/%.c=$(TESTOBJDIR)/%.o) +MAINDEPS = $(CLISRC:$(SRCDIR)/%.c=$(OBJDIR)/%.d) +TESTDEPS = $(TESTSRC:$(SRCDIR)/%.c=$(TESTOBJDIR)/%.d) + +CLIOBJ := $(CLISRC:$(SRCDIR)/%.c=$(OBJDIR)/%.o) +TESTOBJ := $(TESTSRC:$(SRCDIR)/%.c=$(TESTOBJDIR)/%.o) LIBS = CC = gcc -CFLAGS = -g -Wall --std=c99 +CFLAGS = -Wall --std=c99 +MAINCFLAGS = -O3 +TESTCFLAGS = -g .PHONY: default all clean test default: $(BINDIR)/coquet-cli $(BINDIR)/coquet-test all: default -obj/test: - -mkdir obj/test +# .c -> .o $(OBJDIR)/%.o: $(SRCDIR)/%.c - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CFLAGS) $(MAINCFLAGS) -c $< -o $@ + +$(TESTOBJDIR)/%.o: $(SRCDIR)/%.c + $(CC) $(CFLAGS) $(TESTCFLAGS) -DCOQUET_TEST -c $< -o $@ -$(TESTOBJDIR)/%.o: $(SRCDIR)/%.c obj/test - $(CC) $(CFLAGS) -DCOQUET_TEST -c $< -o $@ +# .c -> .d $(OBJDIR)/%.d: $(SRCDIR)/%.c $(CC) -MM -MP -MT $(@:.d=.o) $< > $@ -$(TESTOBJDIR)/%.d: $(SRCDIR)/%.c obj/test +$(TESTOBJDIR)/%.d: $(SRCDIR)/%.c $(CC) -DCOQUET_TEST -MM -MP -MT $(@:.d=.o) $< > $@ -$(BINDIR)/coquet-cli: $(OBJ) $(OBJDIR)/main.o - $(CC) $(OBJ) $(OBJDIR)/main.o -Wall $(LIBS) -o $@ +# .o -> bin + +$(BINDIR)/coquet-cli: $(CLIOBJ) + $(CC) $(CLIOBJ) -Wall $(LIBS) -o $@ -$(BINDIR)/coquet-test: $(TESTOBJ) $(TESTOBJDIR)/test.o - $(CC) $(TESTOBJ) $(TESTOBJDIR)/test.o -Wall $(LIBS) -o $@ +$(BINDIR)/coquet-test: $(TESTOBJ) + $(CC) $(TESTOBJ) -Wall $(LIBS) -o $@ # .PRECIOUS: $(TARGET) $(OBJECTS) @@ -51,5 +58,5 @@ clean: -rm -f $(TESTOBJDIR)/* -rm -f $(BINDIR)/* --include $(DEPS) +-include $(MAINDEPS) -include $(TESTDEPS) diff --git a/src/coquet.h b/src/coquet.h index 9118fac..304f1ad 100644 --- a/src/coquet.h +++ b/src/coquet.h @@ -32,6 +32,8 @@ char * coquet_error_string(coquet_t *cq, int error); #ifdef COQUET_TEST void test_bail(coquet_t * cq, int error_code); void test_unlink(char *path); +void test_file_compare(char *got, char *expected); +void test_assert(int is_true, char *msg); #endif #endif diff --git a/src/superblock.c b/src/superblock.c index 3eaa86e..c901a70 100644 --- a/src/superblock.c +++ b/src/superblock.c @@ -30,15 +30,12 @@ * +-------------------+ * | block_size | 0 1 * | nursery_size | 1 1 + * | unused | 2 126 * +-------------------+ - * | unused | 2 509 + * | description | 128 128 * +-------------------+ - * | reserved | 511 1 + * | unused | 256 256 * +-------------------+ - * - * The reserved byte is to allow locking to work via superblock page. - * Range must exist to write, hence lock code may write this byte at - * offset 0x00007FFF */ struct cq_super default_super = { @@ -121,8 +118,8 @@ int cq_super_load(coquet_t *cq, struct cq_super *super, bool_t create) { return r; } - r = extract_half(super_bytes,&super_a); - r2 = extract_half(super_bytes+HALF_BYTES,&super_b); + r = !!extract_half(super_bytes,&super_a); + r2 = !!extract_half(super_bytes+HALF_BYTES,&super_b); switch(r*2+r2) { case 3: /* both valid */ use_b = (super_b.sb_serial > super_a.sb_serial); @@ -232,30 +229,69 @@ int cq_super_save(coquet_t *cq, struct cq_super *super, bool_t wait) { void test_superblock() { coquet_t cq; - int r; + int i,r; struct cq_super super; printf("testing superblock\n"); + r = coquet_init(&cq,"tmp/test"); test_bail(&cq,r); - + testvfs_fakerandom(cq.vfs_data,0xA5); + + /* simple load/save test to check data is in the right place */ + test_unlink("tmp/test.coquet"); + r = (cq.vfs_funcs.open)(cq.vfs_data,COQUET_FILE_MAIN,COQUET_CMODE_EITHER); test_bail(&cq,r); - testvfs_fakerandom(cq.vfs_data,0xA5); r = cq_super_load(&cq,&super,1); test_bail(&cq,r); cq_super_save(&cq,&super,1); test_bail(&cq,r); - testvfs_fakerandom(cq.vfs_data,-1); + + super.desired.nursery_size = 11; /* change something for B */ + cq_super_save(&cq,&super,1); + test_bail(&cq,r); r = (cq.vfs_funcs.close)(cq.vfs_data,COQUET_FILE_MAIN); test_bail(&cq,r); + test_file_compare("tmp/test.coquet","testdata/sb1.coquet"); + + /* reopen to check the marshalling */ + r = (cq.vfs_funcs.open)(cq.vfs_data,COQUET_FILE_MAIN,COQUET_CMODE_EITHER); + test_bail(&cq,r); + + r = cq_super_load(&cq,&super,1); + test_bail(&cq,r); + + test_assert(super.version == COQUET_VERSION,"version"); + test_assert(super.sb_serial == 2,"serial"); + test_assert(super.from_b == 1,"from_b"); + test_assert(super.current.block_size == 12,"cbsize"); + test_assert(super.desired.block_size == 12,"dbsize"); + test_assert(super.current.nursery_size == 10,"cnurs"); + test_assert(super.desired.nursery_size == 11,"dnurs"); + for(i=0;i #include #include +#include #include "sha2.h" #include "superblock.h" +void test_assert(int is_true, char *msg) { + if(!is_true) { + fprintf(stderr,"assertion '%s' failed\n",msg); + exit(1); + } +} + void test_unlink(char *path) { int r; @@ -15,6 +23,53 @@ void test_unlink(char *path) { } } +#define RFBUFLEN 1024 +static void readfile(char *path, char **out, int *len) { + int fd, r; + char buffer[RFBUFLEN]; + + *out = NULL; + *len = 0; + fd = open(path,O_RDONLY); + if(fd<0) { + fprintf(stderr,"failed to read '%s': %s\n",path,strerror(errno)); + exit(1); + } + while(1) { + r = read(fd,buffer,RFBUFLEN); + if(r<0) { + fprintf(stderr,"failed to read '%s': %s\n",path,strerror(errno)); + exit(1); + } else if(r>0) { + *out = realloc(*out,(*len)+r); + if(*out == NULL) { + fprintf(stderr,"realloc failed\n"); + exit(1); + } + memcpy((*out)+(*len),buffer,r); + *len += r; + + } else { + break; + } + } +} + +void test_file_compare(char *got, char *expected) { + char *got_data, *exp_data; + int got_len, exp_len; + + readfile(got,&got_data,&got_len); + readfile(expected,&exp_data,&exp_len); + if(got_len != exp_len || memcmp(got_data,exp_data,exp_len)) { + /* different! */ + fprintf(stderr,"'%s' (got) and '%s' (expected) differ\n",got,expected); + exit(1); + } + free(got_data); + free(exp_data); +} + void test_bail(coquet_t * cq, int error_code) { char *msg; diff --git a/src/unix.c b/src/unix.c index 87bdd74..6a57c4d 100644 --- a/src/unix.c +++ b/src/unix.c @@ -330,7 +330,7 @@ static int unix_lock(void * vfs_data, int which_lock, int lock_mode, } /* Lock region needs to exist. We can append zeroes.*/ - r = min_size(pd,SUPERBLOCK_LAST_OFFSET); + r = min_size(pd,SUPER_BYTES+LOCK_BLOCK*NUM_LOCKS); if(r != COQUET_RET_OK) { return r; } diff --git a/testdata/sb1.coquet b/testdata/sb1.coquet new file mode 100644 index 0000000..669f78d Binary files /dev/null and b/testdata/sb1.coquet differ