Add test/runner.c; Fix test failure due to allocating wrong size for linkmap; Overall cleanup;
This commit is contained in:
parent
a4fb6c7060
commit
ebf8b1c901
7 changed files with 83 additions and 51 deletions
3
Makefile
3
Makefile
|
@ -98,12 +98,11 @@ install_shared: libhaggis.so
|
||||||
test: libhaggis.a
|
test: libhaggis.a
|
||||||
$(MAKE) -C test
|
$(MAKE) -C test
|
||||||
|
|
||||||
testclean:
|
testclean: clean
|
||||||
$(MAKE) -C test clean
|
$(MAKE) -C test clean
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.a *.so *.o haggis
|
rm -rf *.a *.so *.o haggis
|
||||||
$(MAKE) -C test clean
|
|
||||||
|
|
||||||
.PHONY: all bin shared static clean install install_include install_man \
|
.PHONY: all bin shared static clean install install_include install_man \
|
||||||
install_static install_shared testclean test
|
install_static install_shared testclean test
|
||||||
|
|
|
@ -5,10 +5,6 @@ libdir = $(DESTDIR)$(PREFIX)/lib
|
||||||
sharedir = $(DESTDIR)$(PREFIX)/share
|
sharedir = $(DESTDIR)$(PREFIX)/share
|
||||||
mandir = $(sharedir)/man
|
mandir = $(sharedir)/man
|
||||||
docdir = $(sharedir)/doc/haggis
|
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
|
# Comment this line if your OS ships libmd as part of libc
|
||||||
# (NetBSD, OpenBSD)
|
# (NetBSD, OpenBSD)
|
||||||
LIBS += -lmd
|
LIBS += -lmd
|
||||||
|
|
1
haggis.c
1
haggis.c
|
@ -686,7 +686,6 @@ haggis_node *haggis_create_node(
|
||||||
msg = haggis_msg_init(NodeCreated, body);
|
msg = haggis_msg_init(NodeCreated, body);
|
||||||
haggis_mq_push(mq, msg);
|
haggis_mq_push(mq, msg);
|
||||||
} else if (S_ISREG(st.st_mode)) {
|
} else if (S_ISREG(st.st_mode)) {
|
||||||
node->filetype.tag = normal;
|
|
||||||
res = haggis_init_file_node(node, &st, a, map, mq);
|
res = haggis_init_file_node(node, &st, a, map, mq);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -118,11 +118,8 @@ typedef struct {
|
||||||
|
|
||||||
#define HAGGIS_BUCKETS_BASE 64
|
#define HAGGIS_BUCKETS_BASE 64
|
||||||
|
|
||||||
typedef struct __bucket {
|
typedef struct {
|
||||||
union {
|
ino_t key;
|
||||||
ino_t val;
|
|
||||||
uint8_t bytes[sizeof(ino_t)];
|
|
||||||
} key;
|
|
||||||
uint64_t hash;
|
uint64_t hash;
|
||||||
char *path;
|
char *path;
|
||||||
} haggis_bucket;
|
} haggis_bucket;
|
||||||
|
|
25
linkmap.c
25
linkmap.c
|
@ -34,6 +34,7 @@
|
||||||
#include "haggis_private.h"
|
#include "haggis_private.h"
|
||||||
|
|
||||||
#include <limits.h> // PATH_MAX
|
#include <limits.h> // PATH_MAX
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h> // calloc, free
|
#include <stdlib.h> // calloc, free
|
||||||
#include <string.h> // strndup
|
#include <string.h> // strndup
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ haggis_linkmap* haggis_linkmap_init() {
|
||||||
map = calloc(1, sizeof(haggis_linkmap));
|
map = calloc(1, sizeof(haggis_linkmap));
|
||||||
if (map == NULL)
|
if (map == NULL)
|
||||||
return 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) {
|
if (map->buckets == NULL) {
|
||||||
free(map);
|
free(map);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -86,7 +87,7 @@ void haggis_linkmap_deinit(haggis_linkmap *self) {
|
||||||
int haggis_linkmap_expand(haggis_linkmap *self) {
|
int haggis_linkmap_expand(haggis_linkmap *self) {
|
||||||
haggis_bucket *buckets_new;
|
haggis_bucket *buckets_new;
|
||||||
haggis_bucket *buckets_old;
|
haggis_bucket *buckets_old;
|
||||||
size_t i, hash, idx;
|
size_t i, idx;
|
||||||
|
|
||||||
buckets_new = calloc(self->capacity + HAGGIS_BUCKETS_BASE, sizeof(haggis_bucket));
|
buckets_new = calloc(self->capacity + HAGGIS_BUCKETS_BASE, sizeof(haggis_bucket));
|
||||||
if (buckets_new == NULL)
|
if (buckets_new == NULL)
|
||||||
|
@ -95,10 +96,9 @@ int haggis_linkmap_expand(haggis_linkmap *self) {
|
||||||
self->buckets[i].path = NULL;
|
self->buckets[i].path = NULL;
|
||||||
}
|
}
|
||||||
for (i = 0; i < self->capacity; i++) {
|
for (i = 0; i < self->capacity; i++) {
|
||||||
if (self->buckets[i].key.val != 0) {
|
if (self->buckets[i].key != 0) {
|
||||||
hash = hash_fnv1a_64(&self->buckets[i].key.bytes[0], sizeof(ino_t));
|
|
||||||
self ->capacity += HAGGIS_BUCKETS_BASE;
|
self ->capacity += HAGGIS_BUCKETS_BASE;
|
||||||
idx = self->capacity % hash;
|
idx = self->capacity % self->buckets[i].hash;
|
||||||
buckets_new[idx] = self->buckets[i];
|
buckets_new[idx] = self->buckets[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,7 @@ char* haggis_linkmap_get_or_add(haggis_linkmap *self, ino_t inode, char * path)
|
||||||
} key;
|
} key;
|
||||||
char * target = NULL;
|
char * target = NULL;
|
||||||
size_t idx, hash, i;
|
size_t idx, hash, i;
|
||||||
|
haggis_bucket *bucket;
|
||||||
|
|
||||||
pthread_mutex_lock(&self->mutex);
|
pthread_mutex_lock(&self->mutex);
|
||||||
if (self->len >= self->capacity)
|
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));
|
hash = hash_fnv1a_64(key.bytes, sizeof(ino_t));
|
||||||
idx = hash % self->capacity;
|
idx = hash % self->capacity;
|
||||||
for (i = 0; i < self->capacity; i++) {
|
for (i = 0; i < self->capacity; i++) {
|
||||||
if (self->buckets[idx].key.val == inode) {
|
bucket = &self->buckets[idx];
|
||||||
target = strndup(self->buckets[idx].path, PATH_MAX - 1);
|
if (bucket->key == inode) {
|
||||||
self->buckets[idx].path = path;
|
target = strndup(bucket->path, PATH_MAX - 1);
|
||||||
break;
|
break;
|
||||||
} else if (self->buckets[idx].key.val == 0) {
|
} else if (bucket->key == 0) {
|
||||||
self->buckets[idx].key.val = inode;
|
bucket->path = path;
|
||||||
self->buckets[idx].hash = hash;
|
bucket->key = inode;
|
||||||
self->buckets[idx].path = path;
|
bucket->hash = hash;
|
||||||
self->len++;
|
self->len++;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -9,51 +10,83 @@
|
||||||
#include "haggis.h"
|
#include "haggis.h"
|
||||||
#include "mq.h"
|
#include "mq.h"
|
||||||
|
|
||||||
int main() {
|
|
||||||
haggis_node *node0 = NULL, *node1 = NULL;
|
haggis_node *node0 = NULL, *node1 = NULL;
|
||||||
haggis_linkmap *map = 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() {
|
||||||
|
const char *orig = "Makefile";
|
||||||
|
const char *lnk = "output/Makefile";
|
||||||
haggis_mq mq;
|
haggis_mq mq;
|
||||||
haggis_msg *msg;
|
haggis_msg *msg;
|
||||||
char *orig = "Makefile";
|
|
||||||
char *lnk = "output/Makefile";
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
map = haggis_linkmap_init();
|
map = haggis_linkmap_init();
|
||||||
assert(map != NULL);
|
if (map == NULL)
|
||||||
|
log_and_die("OOM while creating linkmap\n");
|
||||||
if (haggis_mq_init(&mq))
|
if (haggis_mq_init(&mq))
|
||||||
return errno;
|
return errno;
|
||||||
unlink(lnk);
|
unlink(lnk);
|
||||||
ret = link(orig, 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;
|
if (ret) return ret;
|
||||||
node1 = haggis_create_node(lnk, sha256, map, &mq);
|
node0 = haggis_create_node("Makefile", sha256, map, &mq);
|
||||||
assert(node1 != NULL);
|
if (node0 == NULL)
|
||||||
assert(node1->filetype.tag == hardlink);
|
log_and_die("OOM while creating Node 0\n");
|
||||||
assert(memcmp(node1->name.name, lnk, 15) == 0);
|
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);
|
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);
|
haggis_node_deinit(node0);
|
||||||
ret = haggis_extract_node(node1, "output/extracted", &mq);
|
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);
|
haggis_node_deinit(node1);
|
||||||
msg = haggis_mq_pop(&mq);
|
msg = haggis_mq_pop(&mq);
|
||||||
assert(msg->tag == NodeCreated);
|
if (msg->tag != NodeCreated)
|
||||||
assert(memcmp(msg->body.f_name, orig, 8) == 0);
|
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);
|
haggis_msg_deinit(msg);
|
||||||
msg = haggis_mq_pop(&mq);
|
msg = haggis_mq_pop(&mq);
|
||||||
assert(msg->tag == NodeCreated);
|
if (msg->tag != NodeCreated)
|
||||||
assert(memcmp(msg->body.f_name, lnk, 15) == 0);
|
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);
|
haggis_msg_deinit(msg);
|
||||||
msg = haggis_mq_pop(&mq);
|
msg = haggis_mq_pop(&mq);
|
||||||
assert(msg->tag == NodeExtracted);
|
if (msg->tag != NodeExtracted)
|
||||||
assert(memcmp(msg->body.f_name, orig, 8) == 0);
|
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);
|
haggis_msg_deinit(msg);
|
||||||
msg = haggis_mq_pop(&mq);
|
msg = haggis_mq_pop(&mq);
|
||||||
assert(msg->tag == NodeExtracted);
|
if (msg->tag != NodeExtracted)
|
||||||
assert(memcmp(msg->body.f_name, lnk, 15) == 0);
|
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_msg_deinit(msg);
|
||||||
haggis_linkmap_deinit(map);
|
haggis_linkmap_deinit(map);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -2,17 +2,24 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
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;
|
FILE *pipe;
|
||||||
char cmd[100];
|
char cmd[100], output[500];
|
||||||
|
|
||||||
total = argc-1;
|
total = argc-1;
|
||||||
printf("\n\t=== \033[0;33mRunning %i tests\033[0m ===\n", total);
|
printf("\n\t=== \033[0;33mRunning %i tests\033[0m ===\n", total);
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
snprintf(cmd, 100, "./%s", argv[i]);
|
snprintf(cmd, 100, "./%s", argv[i]);
|
||||||
printf("%-25s", argv[i]);
|
printf("%-25s", argv[i]);
|
||||||
pipe = popen(cmd, "r");
|
pipe = popen(cmd, "w");
|
||||||
|
read = fread(&output, 1, 500, pipe);
|
||||||
ret = pclose(pipe);
|
ret = pclose(pipe);
|
||||||
|
if (read) {
|
||||||
|
fail++;
|
||||||
|
printf("\033[0;31mFailed\033[0m\n");
|
||||||
|
fprintf(stderr, "%s\n", &output);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
switch (WEXITSTATUS(ret)) {
|
switch (WEXITSTATUS(ret)) {
|
||||||
case 0:
|
case 0:
|
||||||
pass++;
|
pass++;
|
||||||
|
|
Loading…
Add table
Reference in a new issue