Add test/runner.c; Fix test failure due to allocating wrong size for linkmap; Overall cleanup;

This commit is contained in:
Nathan Fisher 2024-04-17 03:05:41 -04:00
parent a4fb6c7060
commit ebf8b1c901
7 changed files with 83 additions and 51 deletions

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -34,6 +34,7 @@
#include "haggis_private.h"
#include <limits.h> // PATH_MAX
#include <stdio.h>
#include <stdlib.h> // calloc, free
#include <string.h> // 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 {

View file

@ -1,5 +1,6 @@
#include <errno.h>
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -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;

View file

@ -2,17 +2,24 @@
#include <stdlib.h>
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++;