From ebf8b1c901eab09dfaa51e6d5c67500908cda6a3 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Wed, 17 Apr 2024 03:05:41 -0400 Subject: [PATCH] Add test/runner.c; Fix test failure due to allocating wrong size for linkmap; Overall cleanup; --- Makefile | 3 +- config.mk.in | 4 -- haggis.c | 1 - include/haggis.h | 7 +--- linkmap.c | 27 ++++++------ test/extract_hardlink_node.c | 79 +++++++++++++++++++++++++----------- test/runner.c | 13 ++++-- 7 files changed, 83 insertions(+), 51 deletions(-) diff --git a/Makefile b/Makefile index f89f210..f1a3825 100644 --- a/Makefile +++ b/Makefile @@ -98,12 +98,11 @@ install_shared: libhaggis.so test: libhaggis.a $(MAKE) -C test -testclean: +testclean: clean $(MAKE) -C test clean clean: rm -rf *.a *.so *.o haggis - $(MAKE) -C test clean .PHONY: all bin shared static clean install install_include install_man \ install_static install_shared testclean test diff --git a/config.mk.in b/config.mk.in index f89317e..5906546 100644 --- a/config.mk.in +++ b/config.mk.in @@ -5,10 +5,6 @@ libdir = $(DESTDIR)$(PREFIX)/lib sharedir = $(DESTDIR)$(PREFIX)/share mandir = $(sharedir)/man docdir = $(sharedir)/doc/haggis -# We need an `echo` program that doesn't screw with terminal escape sequences. -# This only matters if /bin/sh is a symlink to dash, as the echo builtin in dash -# will screw with them and pass them as printed characters. -ECHO = /bin/echo # Comment this line if your OS ships libmd as part of libc # (NetBSD, OpenBSD) LIBS += -lmd diff --git a/haggis.c b/haggis.c index a2311ae..1261941 100644 --- a/haggis.c +++ b/haggis.c @@ -686,7 +686,6 @@ haggis_node *haggis_create_node( msg = haggis_msg_init(NodeCreated, body); haggis_mq_push(mq, msg); } else if (S_ISREG(st.st_mode)) { - node->filetype.tag = normal; res = haggis_init_file_node(node, &st, a, map, mq); if (res != 0) return NULL; diff --git a/include/haggis.h b/include/haggis.h index 35362c5..e19545a 100644 --- a/include/haggis.h +++ b/include/haggis.h @@ -118,11 +118,8 @@ typedef struct { #define HAGGIS_BUCKETS_BASE 64 -typedef struct __bucket { - union { - ino_t val; - uint8_t bytes[sizeof(ino_t)]; - } key; +typedef struct { + ino_t key; uint64_t hash; char *path; } haggis_bucket; diff --git a/linkmap.c b/linkmap.c index a25cb4a..94aed06 100644 --- a/linkmap.c +++ b/linkmap.c @@ -34,6 +34,7 @@ #include "haggis_private.h" #include // PATH_MAX +#include #include // calloc, free #include // strndup @@ -69,7 +70,7 @@ haggis_linkmap* haggis_linkmap_init() { map = calloc(1, sizeof(haggis_linkmap)); if (map == NULL) return NULL; - map->buckets = calloc(HAGGIS_BUCKETS_BASE, sizeof(size_t)); + map->buckets = calloc(HAGGIS_BUCKETS_BASE, sizeof(haggis_bucket)); if (map->buckets == NULL) { free(map); return NULL; @@ -86,7 +87,7 @@ void haggis_linkmap_deinit(haggis_linkmap *self) { int haggis_linkmap_expand(haggis_linkmap *self) { haggis_bucket *buckets_new; haggis_bucket *buckets_old; - size_t i, hash, idx; + size_t i, idx; buckets_new = calloc(self->capacity + HAGGIS_BUCKETS_BASE, sizeof(haggis_bucket)); if (buckets_new == NULL) @@ -95,10 +96,9 @@ int haggis_linkmap_expand(haggis_linkmap *self) { self->buckets[i].path = NULL; } for (i = 0; i < self->capacity; i++) { - if (self->buckets[i].key.val != 0) { - hash = hash_fnv1a_64(&self->buckets[i].key.bytes[0], sizeof(ino_t)); + if (self->buckets[i].key != 0) { self ->capacity += HAGGIS_BUCKETS_BASE; - idx = self->capacity % hash; + idx = self->capacity % self->buckets[i].hash; buckets_new[idx] = self->buckets[i]; } } @@ -109,13 +109,14 @@ int haggis_linkmap_expand(haggis_linkmap *self) { return 0; } -char* haggis_linkmap_get_or_add(haggis_linkmap *self, ino_t inode, char * path) { +char* haggis_linkmap_get_or_add(haggis_linkmap *self, ino_t inode, char *path) { union { ino_t val; u8 bytes[sizeof(ino_t)]; } key; char * target = NULL; size_t idx, hash, i; + haggis_bucket *bucket; pthread_mutex_lock(&self->mutex); if (self->len >= self->capacity) @@ -124,14 +125,14 @@ char* haggis_linkmap_get_or_add(haggis_linkmap *self, ino_t inode, char * path) hash = hash_fnv1a_64(key.bytes, sizeof(ino_t)); idx = hash % self->capacity; for (i = 0; i < self->capacity; i++) { - if (self->buckets[idx].key.val == inode) { - target = strndup(self->buckets[idx].path, PATH_MAX - 1); - self->buckets[idx].path = path; + bucket = &self->buckets[idx]; + if (bucket->key == inode) { + target = strndup(bucket->path, PATH_MAX - 1); break; - } else if (self->buckets[idx].key.val == 0) { - self->buckets[idx].key.val = inode; - self->buckets[idx].hash = hash; - self->buckets[idx].path = path; + } else if (bucket->key == 0) { + bucket->path = path; + bucket->key = inode; + bucket->hash = hash; self->len++; break; } else { diff --git a/test/extract_hardlink_node.c b/test/extract_hardlink_node.c index ccd337b..806d616 100644 --- a/test/extract_hardlink_node.c +++ b/test/extract_hardlink_node.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -9,51 +10,83 @@ #include "haggis.h" #include "mq.h" +haggis_node *node0 = NULL, *node1 = NULL; +haggis_linkmap *map = NULL; + +void log_and_die(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + if (map != NULL) + haggis_linkmap_deinit(map); + if (node0 != NULL) + haggis_node_deinit(node0); + if (node1 != NULL) + haggis_node_deinit(node1); + exit(EXIT_FAILURE); +} + int main() { - haggis_node *node0 = NULL, *node1 = NULL; - haggis_linkmap *map = NULL; + const char *orig = "Makefile"; + const char *lnk = "output/Makefile"; haggis_mq mq; haggis_msg *msg; - char *orig = "Makefile"; - char *lnk = "output/Makefile"; int ret = 0; map = haggis_linkmap_init(); - assert(map != NULL); + if (map == NULL) + log_and_die("OOM while creating linkmap\n"); if (haggis_mq_init(&mq)) return errno; unlink(lnk); ret = link(orig, lnk); - node0 = haggis_create_node(orig, sha256, map, &mq); - assert(node0 != NULL); - assert(node0->filetype.tag == normal); - assert(memcmp(node0->name.name, orig, 8) == 0); if (ret) return ret; - node1 = haggis_create_node(lnk, sha256, map, &mq); - assert(node1 != NULL); - assert(node1->filetype.tag == hardlink); - assert(memcmp(node1->name.name, lnk, 15) == 0); + node0 = haggis_create_node("Makefile", sha256, map, &mq); + if (node0 == NULL) + log_and_die("OOM while creating Node 0\n"); + if (node0->filetype.tag != normal) + log_and_die("Node 0 incorrect tag: %i\n", node0->filetype.tag); + if (memcmp(node0->name.name, orig, 8) != 0) + log_and_die("Filename mismatch\n"); + node1 = haggis_create_node("output/Makefile", sha256, map, &mq); + if (node1 == NULL) + log_and_die("OOM creating node1\n"); + if (node1->filetype.tag != hardlink) + log_and_die("Node 1 incorrect tag: %u\n", node1->filetype.tag); + if (memcmp(node1->name.name, lnk, 15) != 0) + log_and_die("Node 1 incorrect filename\n"); ret = haggis_extract_node(node0, "output/extracted", &mq); - assert(ret == 0); + if (ret) + log_and_die("Error extracting node0: %i\n", ret); haggis_node_deinit(node0); ret = haggis_extract_node(node1, "output/extracted", &mq); - assert(ret == 0); + if (ret) + log_and_die("Error extracting node1: %i\n", ret); haggis_node_deinit(node1); msg = haggis_mq_pop(&mq); - assert(msg->tag == NodeCreated); - assert(memcmp(msg->body.f_name, orig, 8) == 0); + if (msg->tag != NodeCreated) + log_and_die("Incorrect message, expected \"NodeCreated\", got %u\n", msg->tag); + if (memcmp(msg->body.f_name, orig, 9) != 0) + log_and_die("Filename mismatch: expected %s, got %s\n", orig, msg->body.f_name); haggis_msg_deinit(msg); msg = haggis_mq_pop(&mq); - assert(msg->tag == NodeCreated); - assert(memcmp(msg->body.f_name, lnk, 15) == 0); + if (msg->tag != NodeCreated) + log_and_die("Incorrect message, expected \"NodeCreated\", got %u\n", msg->tag); + if (memcmp(msg->body.f_name, lnk, 15) != 0) + log_and_die("Filename mismatch: expected %s, got %s\n", orig, msg->body.f_name); haggis_msg_deinit(msg); msg = haggis_mq_pop(&mq); - assert(msg->tag == NodeExtracted); - assert(memcmp(msg->body.f_name, orig, 8) == 0); + if (msg->tag != NodeExtracted) + log_and_die("Incorrect message, expected \"NodeExtracted\", got %u\n", msg->tag); + if (memcmp(msg->body.f_name, orig, 9) != 0) + log_and_die("Filename mismatch: expected %s, got %s\n", lnk, msg->body.f_name); haggis_msg_deinit(msg); msg = haggis_mq_pop(&mq); - assert(msg->tag == NodeExtracted); - assert(memcmp(msg->body.f_name, lnk, 15) == 0); + if (msg->tag != NodeExtracted) + log_and_die("Incorrect message, expected \"NodeExtracted\", got %u\n", msg->tag); + if (memcmp(msg->body.f_name, lnk, 15) != 0) + log_and_die("Filename mismatch: expected %s, got %s\n", orig, msg->body.f_name); haggis_msg_deinit(msg); haggis_linkmap_deinit(map); return 0; diff --git a/test/runner.c b/test/runner.c index 17603f0..57ef189 100644 --- a/test/runner.c +++ b/test/runner.c @@ -2,17 +2,24 @@ #include int main(int argc, char *argv[]) { - int i, pass = 0, fail = 0, skip = 0, total, ret; + int i, pass = 0, fail = 0, skip = 0, total, ret, read = 0; FILE *pipe; - char cmd[100]; + char cmd[100], output[500]; total = argc-1; printf("\n\t=== \033[0;33mRunning %i tests\033[0m ===\n", total); for (i = 1; i < argc; i++) { snprintf(cmd, 100, "./%s", argv[i]); printf("%-25s", argv[i]); - pipe = popen(cmd, "r"); + pipe = popen(cmd, "w"); + read = fread(&output, 1, 500, pipe); ret = pclose(pipe); + if (read) { + fail++; + printf("\033[0;31mFailed\033[0m\n"); + fprintf(stderr, "%s\n", &output); + continue; + } switch (WEXITSTATUS(ret)) { case 0: pass++;