fort_SOURCES += base64.h base64.c
fort_SOURCES += cache.c cache.h
fort_SOURCES += cachent.c cachent.h
+fort_SOURCES += cachetmp.c cachetmp.h
fort_SOURCES += certificate_refs.h certificate_refs.c
fort_SOURCES += cert_stack.h cert_stack.c
fort_SOURCES += common.c common.h
#include "cache.h"
#include <ftw.h>
-#include <stdatomic.h>
#include <time.h>
#include "alloc.h"
+#include "cachetmp.h"
#include "common.h"
#include "config.h"
#include "configure_ac.h"
// time_t startup_ts; /* When we started the last validation */
} cache;
-static atomic_uint file_counter;
-
#define CACHE_METAFILE "cache.json"
#define TAGNAME_VERSION "fort-version"
#define CACHEDIR_TAG "CACHEDIR.TAG"
-#define TMPDIR "tmp"
#define TAL_METAFILE "tal.json"
#define TAGNAME_TYPE "type"
char *dirname;
int error;
- dirname = get_cache_filename(TMPDIR, true);
+ dirname = get_cache_filename(CACHE_TMPDIR, true);
error = mkdir(dirname, true);
if (error != EEXIST)
free(filename);
}
-/*
- * Returns a unique temporary file name in the local cache. Note, it's a name,
- * and it's pretty much reserved. The file itself will not be created.
- *
- * The file will not be automatically deleted when it is closed or the program
- * terminates.
- *
- * The name of the function is inherited from tmpfile(3).
- *
- * The resulting string needs to be released.
- */
-int
-cache_tmpfile(char **filename)
-{
- struct path_builder pb;
- int error;
-
- error = pb_init_cache(&pb, TMPDIR);
- if (error)
- return error;
-
- error = pb_append_u32(&pb, atomic_fetch_add(&file_counter, 1u));
- if (error) {
- pb_cleanup(&pb);
- return error;
- }
-
- *filename = pb.string;
- return 0;
-}
-
//static char *
//get_tal_json_filename(void)
//{
static void
load_tal_json(void)
{
- cache.rsync = cachent_create_root(false);
- cache.https = cachent_create_root(true);
+ cache.rsync = cachent_root_rsync();
+ cache.https = cachent_root_https();
// char *filename;
// json_t *root;
dl_http(struct cache_node *node)
{
char *tmppath;
+ time_t mtim;
bool changed;
int error;
if (error)
return error;
+ mtim = time(NULL); // XXX
+
error = http_download(node->url, tmppath, node->mtim, &changed);
if (error) {
free(tmppath);
return error;
}
- node->flags |= CNF_CACHED | CNF_FRESH; // XXX on notification, preserve node but not file
- if (changed) {
- node->flags |= CNF_CHANGED;
- node->mtim = time(NULL); // XXX catch -1
- }
+ node->flags |= CNF_CACHED | CNF_FRESH;
+ if (changed)
+ node->mtim = mtim;
node->tmppath = tmppath;
return 0;
}
static void
cleanup_tmp(void)
{
- char *tmpdir = get_cache_filename(TMPDIR, true);
+ char *tmpdir = get_cache_filename(CACHE_TMPDIR, true);
if (nftw(tmpdir, rmf, 32, FTW_DEPTH | FTW_PHYS))
pr_op_warn("Cannot empty the cache's tmp directory: %s",
strerror(errno));
void cache_setup(void); /* Init this module */
void cache_teardown(void); /* Destroy this module */
-int cache_tmpfile(char **); /* Return new unique path in <cache>/tmp/ */
-
void cache_prepare(void); /* Prepare cache for new validation cycle */
void cache_commit(void); /* Finish successful validation cycle */
/* XXX Huh. Looks like this could use a cache_rollback() */
#include "types/path.h"
#include "types/url.h"
-struct cache_node *
-cachent_create_root(bool https)
+static struct cache_node *
+cachent_root(char const *schema, char const *dir)
{
struct cache_node *root;
root = pzalloc(sizeof(struct cache_node));
- root->url = pstrdup(https ? "https://" : "rsync://");
- root->path = join_paths(config_get_local_repository(),
- https ? "https" : "rsync");
+ root->url = (char *)schema;
+ root->path = join_paths(config_get_local_repository(), dir);
root->name = strrchr(root->path, '/') + 1;
+ root->flags = CNF_FREE_PATH;
return root;
}
+struct cache_node *
+cachent_root_rsync(void)
+{
+ return cachent_root("rsync://", "rsync");
+}
+
+struct cache_node *
+cachent_root_https(void)
+{
+ return cachent_root("https://", "https");
+}
+
/* Preorder. @cb returns whether the children should be traversed. */
int
cachent_traverse(struct cache_node *root, bool (*cb)(struct cache_node *))
child->url = pstrndup(url, name - url + namelen);
child->path = inherit_path(parent->path, name, namelen);
child->name = child->url + (name - url);
+ child->flags = CNF_FREE_URL | CNF_FREE_PATH;
if ((parent->flags & RSYNC_INHERIT) == RSYNC_INHERIT)
- child->flags = RSYNC_INHERIT;
- if (parent->tmppath && !(parent->flags & CNF_RSYNC))
+ child->flags |= RSYNC_INHERIT;
+ if (parent->tmppath && !(parent->flags & CNF_RSYNC)) {
child->tmppath = inherit_path(parent->tmppath, name, namelen);
+ child->flags |= CNF_FREE_TMPPATH;
+ }
child->parent = parent;
HASH_ADD_KEYPTR(hh, parent->children, child->name, namelen, child);
if (node->parent != NULL)
HASH_DEL(node->parent->children, node);
- free(node->url);
- free(node->path);
- free(node->tmppath);
+ if (node->flags & CNF_FREE_URL)
+ free(node->url);
+ if (node->flags & CNF_FREE_PATH)
+ free(node->path);
+ if (node->flags & CNF_FREE_TMPPATH)
+ free(node->tmppath);
free(node);
return valid;
printf("%s", (node->flags & CNF_RSYNC) ? "rsync " : "");
printf("%s", (node->flags & CNF_CACHED) ? "cached " : "");
printf("%s", (node->flags & CNF_FRESH) ? "fresh " : "");
- printf("%s", (node->flags & CNF_CHANGED) ? "changed " : "");
printf("%s", (node->flags & CNF_TOUCHED) ? "touched " : "");
printf("%s", (node->flags & CNF_VALID) ? "valid " : "");
printf("%s", (node->flags & CNF_NOTIFICATION) ? "notification " : "");
* "Allegedly" because we might have rsync'd an ancestor.
*/
#define CNF_FRESH (1 << 2)
-/*
- * Did it change between the previous cycle and the current one?
- * (This is HTTP and RRDP only; rsync doesn't tell us.)
- */
-#define CNF_CHANGED (1 << 3)
/* Was it read during the current cycle? */
#define CNF_TOUCHED (1 << 4)
/*
/* Withdrawn by RRDP? */
#define CNF_WITHDRAWN (1 << 7)
+#define CNF_FREE_URL (1 << 8)
+#define CNF_FREE_PATH (1 << 9)
+#define CNF_FREE_TMPPATH (1 << 10)
+
/*
* Flags for children of downloaded rsync nodes that should be cleaned later.
* (FRESH prevents redownload.)
char *tmppath; /* path/to/cache/tmp/1234 */
/* Only if flags & CNF_NOTIFICATION */
- struct cachefile_notification notif;
+ struct cachefile_notification rrdp;
struct cache_node *parent; /* Tree parent */
struct cache_node *children; /* Tree children */
UT_hash_handle hh; /* Hash table hook */
};
-struct cache_node *cachent_create_root(bool);
+struct cache_node *cachent_root_rsync(void);
+struct cache_node *cachent_root_https(void);
int cachent_traverse(struct cache_node *, bool (*cb)(struct cache_node *));
--- /dev/null
+#include "cachetmp.h"
+
+#include <stdatomic.h>
+#include "types/path.h"
+
+static atomic_uint file_counter;
+
+/*
+ * Returns a unique temporary file name in the local cache. Note, it's a name,
+ * and it's pretty much reserved. The file itself will not be created.
+ *
+ * The file will not be automatically deleted when it is closed or the program
+ * terminates.
+ *
+ * The name of the function is inherited from tmpfile(3).
+ *
+ * The resulting string needs to be released.
+ */
+int
+cache_tmpfile(char **filename)
+{
+ struct path_builder pb;
+ int error;
+
+ error = pb_init_cache(&pb, CACHE_TMPDIR);
+ if (error)
+ return error;
+
+ error = pb_append_u32(&pb, atomic_fetch_add(&file_counter, 1u));
+ if (error) {
+ pb_cleanup(&pb);
+ return error;
+ }
+
+ *filename = pb.string;
+ return 0;
+}
--- /dev/null
+#ifndef SRC_CACHETMP_H_
+#define SRC_CACHETMP_H_
+
+#define CACHE_TMPDIR "tmp"
+
+int cache_tmpfile(char **); /* Return new unique path in <cache>/tmp/ */
+
+#endif /* SRC_CACHETMP_H_ */
}
int
-file_write_full(char const *path, unsigned char *content, size_t content_len)
+file_write_full(char const *path, unsigned char const *content,
+ size_t content_len)
{
FILE *out;
size_t written;
int file_open(char const *, FILE **, struct stat *);
int file_write(char const *, char const *, FILE **);
-int file_write_full(char const *, unsigned char *, size_t);
+int file_write_full(char const *, unsigned char const *, size_t);
void file_close(FILE *);
int file_load(char const *, struct file_contents *, bool);
size_t actual_len;
int error;
+ pr_val_debug("Validating file hash: %s", path);
+
error = hash_file(algorithm, path, actual, &actual_len);
if (error)
return error;
xmlInitParser();
- rngparser = xmlRelaxNGNewMemParserCtxt(RRDP_V1_RNG, RRDP_V1_RNG_SIZE);
+ rngparser = xmlRelaxNGNewMemParserCtxt(RRDP_V1_RNG, strlen(RRDP_V1_RNG));
if (rngparser == NULL) {
error = pr_op_err("XML parser init error: xmlRelaxNGNewMemParserCtxt() returned NULL");
goto cleanup_parser;
" </define>" \
"</grammar>"
-#define RRDP_V1_RNG_SIZE strlen(RRDP_V1_RNG)
-
int relax_ng_init(void);
void relax_ng_cleanup(void);
struct parser_args {
struct rrdp_session *session;
- struct cache_node *rpp;
+ struct cache_node *notif;
};
static BIGNUM *
}
static int
-handle_publish(xmlTextReaderPtr reader, struct cache_node *rpp)
+handle_publish(xmlTextReaderPtr reader, struct cache_node *notif)
{
struct publish tag = { 0 };
- struct cache_node *node;
+ struct cache_node *subtree, *node;
int error;
error = parse_publish(reader, &tag);
if (error)
goto end;
+ pr_val_debug("- publish %s", tag.meta.uri);
+
+ if (!notif->rrdp.subtree) {
+ subtree = pzalloc(sizeof(struct cache_node));
+ subtree->url = "rsync://";
+ subtree->path = notif->path;
+ subtree->name = strrchr(subtree->path, '/') + 1;
+ subtree->tmppath = notif->tmppath;
+ notif->rrdp.subtree = subtree;
+ }
- // XXX Not going to pass URL validation.
- node = cachent_provide(rpp, tag.meta.uri);
+ node = cachent_provide(notif->rrdp.subtree, tag.meta.uri);
if (!node) {
+ // XXX outdated msg
error = pr_val_err("Broken RRDP: <publish> is attempting to create file '%s' outside of its publication point '%s'.",
- tag.meta.uri, rpp->url);
+ tag.meta.uri, notif->url);
goto end;
}
goto end;
}
+ pr_val_debug("Caching file: %s", node->tmppath);
error = file_write_full(node->tmppath, tag.content, tag.content_len);
end: metadata_cleanup(&tag.meta);
}
static int
-handle_withdraw(xmlTextReaderPtr reader, struct cache_node *rpp)
+handle_withdraw(xmlTextReaderPtr reader, struct cache_node *notif)
{
struct withdraw tag = { 0 };
struct cache_node *node;
if (error)
goto end;
- // XXX Not going to pass URL validation.
- node = cachent_provide(rpp, tag.meta.uri);
+ pr_val_debug("- withdraw: %s", tag.meta.uri);
+
+ node = cachent_provide(notif->rrdp.subtree, tag.meta.uri);
if (!node) {
+ // XXX outdated msg
error = pr_val_err("Broken RRDP: <withdraw> is attempting to delete file '%s' outside of its publication point '%s'.",
- tag.meta.uri, rpp->url);
+ tag.meta.uri, notif->url);
goto end;
}
}
static int
-parse_notification(struct cache_node *notif, struct update_notification *result)
+parse_notification(char const *url, char const *path,
+ struct update_notification *result)
{
int error;
- update_notification_init(result, notif->url);
+ update_notification_init(result, url);
- error = relax_ng_parse(notif->tmppath, xml_read_notif, result);
+ error = relax_ng_parse(path, xml_read_notif, result);
if (error)
update_notification_cleanup(result);
switch (type) {
case XML_READER_TYPE_ELEMENT:
if (xmlStrEqual(name, BAD_CAST RRDP_ELEM_PUBLISH))
- error = handle_publish(reader, args->rpp);
+ error = handle_publish(reader, args->notif);
else if (xmlStrEqual(name, BAD_CAST RRDP_ELEM_SNAPSHOT))
error = validate_session(reader, args->session);
else
static int
parse_snapshot(struct rrdp_session *session, char const *path,
- struct cache_node *rpp)
+ struct cache_node *notif)
{
- struct parser_args args = { .session = session, .rpp = rpp };
+ struct parser_args args = { .session = session, .notif = notif };
return relax_ng_parse(path, xml_read_snapshot, &args);
}
}
static int
-handle_snapshot(struct update_notification *notif, struct cache_node *rpp)
+handle_snapshot(struct update_notification *new, struct cache_node *notif)
{
char *tmppath;
int error;
- pr_val_debug("Processing snapshot '%s'.", notif->snapshot.uri);
- fnstack_push(notif->snapshot.uri);
+ pr_val_debug("Processing snapshot '%s'.", new->snapshot.uri);
+ fnstack_push(new->snapshot.uri);
- error = dl_tmp(notif->snapshot.uri, &tmppath);
+ error = dl_tmp(new->snapshot.uri, &tmppath);
if (error)
goto end1;
- error = validate_hash(¬if->snapshot, tmppath);
+ error = validate_hash(&new->snapshot, tmppath);
if (error)
goto end2;
- error = parse_snapshot(¬if->session, tmppath, rpp);
+ error = parse_snapshot(&new->session, tmppath, notif);
delete_file(tmppath);
end2: free(tmppath);
switch (type) {
case XML_READER_TYPE_ELEMENT:
if (xmlStrEqual(name, BAD_CAST RRDP_ELEM_PUBLISH))
- error = handle_publish(reader, args->rpp);
+ error = handle_publish(reader, args->notif);
else if (xmlStrEqual(name, BAD_CAST RRDP_ELEM_WITHDRAW))
- error = handle_withdraw(reader, args->rpp);
+ error = handle_withdraw(reader, args->notif);
else if (xmlStrEqual(name, BAD_CAST RRDP_ELEM_DELTA))
error = validate_session(reader, args->session);
else
static int
parse_delta(struct update_notification *notif, struct notification_delta *delta,
- char const *path, struct cache_node *node)
+ char const *path, struct cache_node *notif_node)
{
struct parser_args args;
struct rrdp_session session;
session.session_id = notif->session.session_id;
session.serial = delta->serial;
args.session = &session;
- args.rpp = node;
+ args.notif = notif_node;
return relax_ng_parse(path, xml_read_delta, &args);
}
static int
handle_delta(struct update_notification *notif,
- struct notification_delta *delta, struct cache_node *node)
+ struct notification_delta *delta, struct cache_node *notif_node)
{
char *tmppath;
int error;
error = dl_tmp(delta->meta.uri, &tmppath);
if (error)
goto end;
- error = parse_delta(notif, delta, tmppath, node);
+ error = parse_delta(notif, delta, tmppath, notif_node);
delete_file(tmppath);
free(tmppath);
}
static int
-handle_deltas(struct update_notification *notif, struct cache_node *node)
+handle_deltas(struct update_notification *notif, struct cache_node *notif_node)
{
struct rrdp_serial *old;
struct rrdp_serial *new;
return -ENOENT;
}
- old = &node->notif.session.serial;
+ old = ¬if_node->rrdp.session.serial;
new = ¬if->session.serial;
pr_val_debug("Handling RRDP delta serials %s-%s.", old->str, new->str);
old->str, new->str);
for (d = notif->deltas.len - diff; d < notif->deltas.len; d++) {
- error = handle_delta(notif, ¬if->deltas.array[d], node);
+ error = handle_delta(notif, ¬if->deltas.array[d], notif_node);
if (error)
return error;
}
return 0;
}
-static int
-dl_notif(struct cache_node *notif)
+static bool
+dl_notif(struct cache_node *notif, struct update_notification *new)
{
char *tmppath;
+ time_t mtim;
bool changed;
- int error;
- error = cache_tmpfile(&tmppath);
- if (error)
- return error;
+ notif->dlerr = cache_tmpfile(&tmppath);
+ if (notif->dlerr)
+ return false;
- error = http_download(notif->url, tmppath, notif->mtim, &changed);
- if (error) {
- free(tmppath);
- return error;
+ mtim = time(NULL); // XXX
+ changed = false;
+ notif->dlerr = http_download(notif->url, tmppath, notif->mtim, &changed);
+ notif->flags |= CNF_FRESH;
+
+ if (notif->dlerr)
+ goto end;
+ if (!changed) {
+ pr_val_debug("The Notification has not changed.");
+ goto end;
}
- // XXX notif->flags |= CNF_CACHED | CNF_FRESH;
- if (changed) {
- notif->mtim = time(NULL); // XXX
- notif->tmppath = tmppath;
- } else {
- free(tmppath);
+ notif->mtim = mtim; /* XXX should happen much later */
+ notif->dlerr = parse_notification(notif->url, tmppath, new);
+ if (notif->dlerr)
+ goto end;
+
+ if (remove(tmppath) == -1) {
+ notif->dlerr = errno;
+ pr_val_err("Can't remove notification's temporal file: %s",
+ strerror(notif->dlerr));
+ goto end;
+ }
+ if (mkdir(tmppath, 0777) == -1) {
+ notif->dlerr = errno;
+ pr_val_err("Can't create notification's temporal directory: %s",
+ strerror(notif->dlerr));
+ goto end;
}
- return 0;
+ notif->tmppath = tmppath;
+ return true;
+
+end: free(tmppath);
+ return false;
}
/*
* Downloads the Update Notification @notif, and updates the cache accordingly.
*
* "Updates the cache accordingly" means it downloads the missing deltas or
- * snapshot, and explodes them into @rpp's tmp directory.
+ * snapshot, and explodes them into @notif's tmp directory.
*/
int
rrdp_update(struct cache_node *notif)
struct cachefile_notification *old;
struct update_notification new;
int serial_cmp;
- int error;
fnstack_push(notif->url);
pr_val_debug("Processing notification.");
- ///////////////////////////////////////////////////////////////////////
-
- error = dl_notif(notif);
- if (error)
- goto end;
-
- if (!notif->tmppath) {
- pr_val_debug("The Notification has not changed.");
- goto end;
- }
-
- error = parse_notification(notif, &new);
- if (error)
- goto end;
-
- remove(notif->tmppath); // XXX
- if (mkdir(notif->tmppath, 0777) == -1) {
- error = errno;
- pr_val_err("Can't create notification's temporal directory: %s",
- strerror(error));
- goto clean_notif;
- }
-
- ///////////////////////////////////////////////////////////////////////
+ if (!dl_notif(notif, &new))
+ goto end; /* Unchanged or error */
pr_val_debug("New session/serial: %s/%s", new.session.session_id,
new.session.serial.str);
if (!(notif->flags & CNF_NOTIFICATION)) {
pr_val_debug("This is a new Notification.");
- error = handle_snapshot(&new, notif);
- if (error)
+ notif->dlerr = handle_snapshot(&new, notif);
+ if (notif->dlerr)
goto clean_notif;
notif->flags |= CNF_NOTIFICATION;
- init_notif(¬if->notif, &new);
+ init_notif(¬if->rrdp, &new);
goto end;
}
- old = ¬if->notif;
+ old = ¬if->rrdp;
serial_cmp = BN_cmp(old->session.serial.num, new.session.serial.num);
if (serial_cmp < 0) {
pr_val_debug("The Notification's serial changed.");
- error = validate_session_desync(old, &new);
- if (error)
+ notif->dlerr = validate_session_desync(old, &new);
+ if (notif->dlerr)
goto snapshot_fallback;
- error = handle_deltas(&new, notif);
- if (error)
+ notif->dlerr = handle_deltas(&new, notif);
+ if (notif->dlerr)
goto snapshot_fallback;
- error = update_notif(old, &new);
- if (!error)
+ notif->dlerr = update_notif(old, &new);
+ if (!notif->dlerr)
goto end;
/*
* The files are exploded and usable, but @cached is not
snapshot_fallback:
pr_val_debug("Falling back to snapshot.");
- error = handle_snapshot(&new, notif);
- if (error)
+ notif->dlerr = handle_snapshot(&new, notif);
+ if (notif->dlerr)
goto clean_notif;
reset_notif:
clean_notif:
update_notification_cleanup(&new);
-end:
- fnstack_pop();
- return error;
+end: fnstack_pop();
+ return notif->dlerr;
}
#define TAGNAME_SESSION "session_id"
*/
struct cachefile_notification {
struct rrdp_session session;
+ struct cache_node *subtree;
/*
* The 1st one contains the hash of the session.serial delta.
* The 2nd one contains the hash of the session.serial - 1 delta.
#include <errno.h>
#include "alloc.h"
-#include "cache.h"
+#include "cachetmp.h"
#include "common.h"
#include "config.h"
#include "config/filename_format.h"
#include "common.c"
#include "cache.c"
#include "cachent.c"
+#include "cachetmp.c"
#include "cache_util.c"
#include "file.c"
#include "mock.c"
+#include "mock_https.c"
#include "types/path.c"
#include "types/str.c"
#include "types/url.c"
/* Mocks */
static unsigned int rsync_counter; /* Times the rsync function was called */
-static unsigned int https_counter; /* Times the https function was called */
-static int dl_error;
int
rsync_download(char const *src, char const *dst, char const *cmpdir)
return 0;
}
-int
-http_download(char const *src, char const *dst, curl_off_t ims, bool *changed)
-{
- char cmd[61];
-
- https_counter++;
-
- if (dl_error) {
- *changed = false;
- return dl_error;
- }
-
- ck_assert_int_eq(0, mkdir_p(dst, false, 0777));
-
- ck_assert(snprintf(cmd, sizeof(cmd), "touch %s", dst) < sizeof(cmd));
- ck_assert_int_eq(0, system(cmd));
-
- *changed = true;
- return 0;
-}
-
MOCK_ABORT_INT(rrdp_update, struct cache_node *notif)
__MOCK_ABORT(rrdp_notif2json, json_t *, NULL, struct cachefile_notification *notif)
MOCK_VOID(rrdp_notif_free, struct cachefile_notification *notif)
MOCK_ABORT_INT(rrdp_json2notif, json_t *json, struct cachefile_notification **result)
-MOCK(cfg_cache_threshold, time_t, 60 * 60 * 24 * 7, void)
MOCK_VOID(__delete_node_cb, struct cache_node const *node)
/* Helpers */
dl_error = 0;
ck_assert_int_eq(0, system("rm -rf tmp/"));
cache_prepare();
- ck_assert_int_eq(0, system("mkdir -p tmp/rsync"));
- ck_assert_int_eq(0, system("mkdir -p tmp/https"));
+ ck_assert_int_eq(0, system("mkdir -p tmp/rsync tmp/https tmp/tmp"));
}
static int
return true;
}
-static void
-ck_assert_cachent_eq(struct cache_node *expected, struct cache_node *actual)
-{
- struct cache_node *echild, *achild, *tmp;
-
- PR_DEBUG_MSG("Comparing %s vs %s", expected->url, actual->url);
-
- ck_assert_str_eq(expected->url, actual->url);
- ck_assert_str_eq(expected->path, actual->path);
- ck_assert_str_eq(expected->name, actual->name);
- ck_assert_int_eq(expected->flags, actual->flags);
- if (expected->tmppath)
- ck_assert_str_eq(expected->tmppath, actual->tmppath);
- else
- ck_assert_ptr_eq(NULL, actual->tmppath);
-
- HASH_ITER(hh, expected->children, echild, tmp) {
- HASH_FIND(hh, actual->children, echild->name,
- strlen(echild->name), achild);
- if (achild == NULL)
- ck_abort_msg("Expected not found: %s", echild->url);
- ck_assert_cachent_eq(echild, achild);
- }
-
- HASH_ITER(hh, actual->children, achild, tmp) {
- HASH_FIND(hh, expected->children, achild->name,
- strlen(achild->name), echild);
- if (echild == NULL)
- ck_abort_msg("Actual not found: %s", achild->url);
- }
-}
-
static void
ck_cache(struct cache_node *rsync, struct cache_node *https)
{
static void
ck_cache_rsync(struct cache_node *rsync)
{
- ck_cache(rsync, hunode("", NULL));
+ ck_cache(rsync, hunode(HE2UP, NULL));
}
static void
ck_cache_https(struct cache_node *https)
{
- ck_cache(runode("", NULL), https);
+ ck_cache(runode(RE2UP, NULL), https);
}
static time_t
unfreshen(struct cache_node *node)
{
PR_DEBUG_MSG("Unfreshening %s.", node->url);
- node->flags &= ~(CNF_FRESH | CNF_CHANGED | CNF_VALID);
+ node->flags &= ~(CNF_FRESH | CNF_VALID);
node->mtim = epoch;
return true;
}
cache_print();
}
-//static void
-//cache_reset(struct rpki_cache *cache)
-//{
-// struct cache_node *node, *tmp;
-// HASH_ITER(hh, cache->ht, node, tmp)
-// delete_node(cache, node);
-//}
-
static void
cleanup_test(void)
{
printf("==== Startup ====\n");
run_dl_rsync("rsync://a.b.c/d", 0, 1);
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- ruftnode("a.b.c/d", FULL, "tmp/tmp/0", NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL), NULL), NULL));
- /* Redownload same file, nothing should happen */
- printf("==== Redownload sample file ====\n");
+ printf("==== Redownload same file, nothing should happen ====\n");
run_dl_rsync("rsync://a.b.c/d", 0, 0);
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- ruftnode("a.b.c/d", FULL, "tmp/tmp/0", NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL), NULL), NULL));
/*
* rsyncs are recursive, which means if we've been recently asked to
printf("==== Don't redownload child ====\n");
run_dl_rsync("rsync://a.b.c/d/e", 0, 0);
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- ruftnode("a.b.c/d", FULL, "tmp/tmp/0",
- rufnode("a.b.c/d/e", VALIDATED, NULL), NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0",
+ rufnode(RO2UP("a.b.c/d/e"), VALIDATED, NULL), NULL), NULL), NULL));
/*
* rsyncs get truncated, because it results in much faster
printf("==== rsync truncated ====\n");
run_dl_rsync("rsync://x.y.z/m/n/o", 0, 1);
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- ruftnode("a.b.c/d", FULL, "tmp/tmp/0",
- rufnode("a.b.c/d/e", VALIDATED, NULL), NULL), NULL),
- runode("x.y.z",
- ruftnode("x.y.z/m", DOWNLOADED, "tmp/tmp/1",
- rufnode("x.y.z/m/n", BRANCH,
- rufnode("x.y.z/m/n/o", VALIDATED, NULL), NULL), NULL), NULL), NULL));
-
- /* Sibling */
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0",
+ rufnode(RO2UP("a.b.c/d/e"), VALIDATED, NULL), NULL), NULL),
+ runode(RO2UP("x.y.z"),
+ ruftnode(RO2UP("x.y.z/m"), DOWNLOADED, "tmp/tmp/1",
+ rufnode(RO2UP("x.y.z/m/n"), BRANCH,
+ rufnode(RO2UP("x.y.z/m/n/o"), VALIDATED, NULL), NULL), NULL), NULL), NULL));
+
printf("==== Sibling ====\n");
run_dl_rsync("rsync://a.b.c/e/f", 0, 1);
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- ruftnode("a.b.c/d", FULL, "tmp/tmp/0",
- rufnode("a.b.c/d/e", VALIDATED, NULL), NULL),
- ruftnode("a.b.c/e", DOWNLOADED, "tmp/tmp/2",
- rufnode("a.b.c/e/f", VALIDATED, NULL), NULL), NULL),
- runode("x.y.z",
- ruftnode("x.y.z/m", DOWNLOADED, "tmp/tmp/1",
- rufnode("x.y.z/m/n", BRANCH,
- rufnode("x.y.z/m/n/o", VALIDATED, NULL), NULL), NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0",
+ rufnode(RO2UP("a.b.c/d/e"), VALIDATED, NULL), NULL),
+ ruftnode(RO2UP("a.b.c/e"), DOWNLOADED, "tmp/tmp/2",
+ rufnode(RO2UP("a.b.c/e/f"), VALIDATED, NULL), NULL), NULL),
+ runode(RO2UP("x.y.z"),
+ ruftnode(RO2UP("x.y.z/m"), DOWNLOADED, "tmp/tmp/1",
+ rufnode(RO2UP("x.y.z/m/n"), BRANCH,
+ rufnode(RO2UP("x.y.z/m/n/o"), VALIDATED, NULL), NULL), NULL), NULL), NULL));
cleanup_test();
}
{
setup_test();
+ printf("==== Startup ====\n");
dl_error = 0;
run_dl_rsync("rsync://a.b.c/d", 0, 1);
dl_error = -EINVAL;
run_dl_rsync("rsync://a.b.c/e", -EINVAL, 1);
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- ruftnode("a.b.c/d", FULL, "tmp/tmp/0", NULL),
- rufnode("a.b.c/e", FAILED, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL),
+ rufnode(RO2UP("a.b.c/e"), FAILED, NULL), NULL), NULL));
- /* Regardless of error, not reattempted because same iteration */
+ printf("==== Regardless of error, not reattempted because same iteration ====\n");
dl_error = EINVAL;
run_dl_rsync("rsync://a.b.c/e", -EINVAL, 0);
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- ruftnode("a.b.c/d", FULL, "tmp/tmp/0", NULL),
- rufnode("a.b.c/e", FAILED, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL),
+ rufnode(RO2UP("a.b.c/e"), FAILED, NULL), NULL), NULL));
dl_error = 0;
run_dl_rsync("rsync://a.b.c/e", -EINVAL, 0);
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- ruftnode("a.b.c/d", FULL, "tmp/tmp/0", NULL),
- rufnode("a.b.c/e", FAILED, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL),
+ rufnode(RO2UP("a.b.c/e"), FAILED, NULL), NULL), NULL));
cleanup_test();
}
{
setup_test();
- /*
- * First iteration: Tree is created. No prunes, because nothing's
- * outdated.
- */
- printf("==== First iteration: Tree is created ====\n");
+ printf("==== First iteration: Tree is created. No prunes, because nothing's outdated ====\n");
new_iteration(true);
run_dl_rsync("rsync://a.b.c/d", 0, 1);
run_dl_rsync("rsync://a.b.c/e", 0, 1);
run_cleanup();
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- rufnode("a.b.c/d", FULL, NULL),
- rufnode("a.b.c/e", FULL, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ rufnode(RO2UP("a.b.c/d"), FULL, NULL),
+ rufnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
- /* One iteration with no changes, for paranoia */
- printf("==== No changes, for paranoia ====\n");
+ printf("==== One iteration with no changes, for paranoia ====\n");
new_iteration(true);
run_dl_rsync("rsync://a.b.c/d", 0, 1);
run_dl_rsync("rsync://a.b.c/e", 0, 1);
run_cleanup();
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- rufnode("a.b.c/d", FULL, NULL),
- rufnode("a.b.c/e", FULL, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ rufnode(RO2UP("a.b.c/d"), FULL, NULL),
+ rufnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
- /* Add one sibling */
printf("==== Add one sibling ====\n");
new_iteration(true);
run_dl_rsync("rsync://a.b.c/d", 0, 1);
run_dl_rsync("rsync://a.b.c/f", 0, 1);
run_cleanup();
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- rufnode("a.b.c/d", FULL, NULL),
- rufnode("a.b.c/e", FULL, NULL),
- rufnode("a.b.c/f", FULL, NULL), NULL), NULL));
-
- /* Nodes don't get updated, but they're still too young. */
- printf("==== Still too young ====\n");
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ rufnode(RO2UP("a.b.c/d"), FULL, NULL),
+ rufnode(RO2UP("a.b.c/e"), FULL, NULL),
+ rufnode(RO2UP("a.b.c/f"), FULL, NULL), NULL), NULL));
+
+ printf("==== Nodes don't get updated, but they're still too young ====\n");
new_iteration(false);
run_cleanup();
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- rufnode("a.b.c/d", STALE, NULL),
- rufnode("a.b.c/e", STALE, NULL),
- rufnode("a.b.c/f", STALE, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ rufnode(RO2UP("a.b.c/d"), STALE, NULL),
+ rufnode(RO2UP("a.b.c/e"), STALE, NULL),
+ rufnode(RO2UP("a.b.c/f"), STALE, NULL), NULL), NULL));
- /* Remove some branches */
printf("==== Remove some branches ====\n");
new_iteration(true);
run_dl_rsync("rsync://a.b.c/d", 0, 1);
run_cleanup();
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- rufnode("a.b.c/d", FULL, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ rufnode(RO2UP("a.b.c/d"), FULL, NULL), NULL), NULL));
- /* Remove old branch and add sibling at the same time */
- printf("==== Remove old branch + add sibling ====\n");
+ printf("==== Remove old branch and add sibling at the same time ====\n");
new_iteration(true);
run_dl_rsync("rsync://a.b.c/e", 0, 1);
run_cleanup();
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- rufnode("a.b.c/e", FULL, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ rufnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
- /* Try child */
printf("==== Try child ====\n");
new_iteration(true);
run_dl_rsync("rsync://a.b.c/e/f/g", 0, 1);
run_cleanup();
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- rufnode("a.b.c/e", FULL, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ rufnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
- /* Parent again */
printf("==== Parent again ====\n");
new_iteration(true);
run_dl_rsync("rsync://a.b.c/e", 0, 1);
run_cleanup();
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- rufnode("a.b.c/e", FULL, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ rufnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
- /* Empty the tree */
printf("==== Empty the tree ====\n");
new_iteration(true);
run_cleanup();
- ck_cache_rsync(runode("", NULL));
+ ck_cache_rsync(runode(RE2UP, NULL));
- /* Node exists, but file doesn't */
printf("==== Node exists, but file doesn't ====\n");
new_iteration(true);
run_dl_rsync("rsync://a.b.c/e", 0, 1);
run_dl_rsync("rsync://a.b.c/f", 0, 1);
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- ruftnode("a.b.c/e", FULL, "tmp/tmp/B", NULL),
- ruftnode("a.b.c/f", FULL, "tmp/tmp/C", NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ ruftnode(RO2UP("a.b.c/e"), FULL, "tmp/tmp/B", NULL),
+ ruftnode(RO2UP("a.b.c/f"), FULL, "tmp/tmp/C", NULL), NULL), NULL));
run_cleanup();
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- rufnode("a.b.c/e", FULL, NULL),
- rufnode("a.b.c/f", FULL, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ rufnode(RO2UP("a.b.c/e"), FULL, NULL),
+ rufnode(RO2UP("a.b.c/f"), FULL, NULL), NULL), NULL));
ck_assert_int_eq(0, file_rm_rf("tmp/rsync/a.b.c/f"));
run_cleanup();
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- rufnode("a.b.c/e", FULL, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ rufnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
cleanup_test();
}
{
setup_test();
- /* Set up */
printf("==== Set up ====\n");
dl_error = 0;
run_dl_rsync("rsync://a.b.c/d", 0, 1);
dl_error = -EINVAL;
run_dl_rsync("rsync://a.b.c/e", -EINVAL, 1);
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- ruftnode("a.b.c/d", FULL, "tmp/tmp/0", NULL),
- rufnode("a.b.c/e", FAILED, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL),
+ rufnode(RO2UP("a.b.c/e"), FAILED, NULL), NULL), NULL));
- /* Node gets deleted because cached file doesn't exist */
- printf("==== Node deleted because file not found ====\n");
+ printf("==== Node deleted because file doesn't exist ====\n");
run_cleanup();
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- rufnode("a.b.c/d", FULL, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ rufnode(RO2UP("a.b.c/d"), FULL, NULL), NULL), NULL));
- /*
- * Node and file do not get deleted, because the failure is still not
- * that old.
- * Deletion does not depend on success or failure.
- */
printf("==== Node and file preserved because young ====\n");
+ /* (Deletion does not depend on success or failure.) */
new_iteration(false);
dl_error = -EINVAL;
run_dl_rsync("rsync://a.b.c/d", -EINVAL, 1);
ck_cache_rsync(
- runode("",
- runode("a.b.c",
- rufnode("a.b.c/d", DOWNLOADED, NULL), NULL), NULL));
+ runode(RE2UP,
+ runode(RO2UP("a.b.c"),
+ rufnode(RO2UP("a.b.c/d"), DOWNLOADED, NULL), NULL), NULL));
- /* Error is old; gets deleted */
- printf("==== Error deleted because old ====\n");
+ printf("==== Error node deleted because old ====\n");
new_iteration(true);
run_cleanup();
- ck_cache_rsync(runode("", NULL));
+ ck_cache_rsync(runode(RE2UP, NULL));
cleanup_test();
}
/* XXX ================================================================ */
-static const int HDOWNLOADED = CNF_CACHED | CNF_FRESH | CNF_CHANGED;
+static const int HDOWNLOADED = CNF_CACHED | CNF_FRESH;
static const int HVALIDATED = CNF_CACHED | CNF_VALID;
static const int HFULL = HDOWNLOADED | HVALIDATED;
static const int HFAILED = CNF_FRESH;
{
setup_test();
- /* Download *file* e. */
+ printf("==== Download *file* e ====\n");
run_dl_https("https://a.b.c/d/e", 0, 1);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hunode("a.b.c/d",
- huftnode("a.b.c/d/e", HFULL, "tmp/tmp/0", NULL), NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hunode(HO2UP("a.b.c/d"),
+ huftnode(HO2UP("a.b.c/d/e"), HFULL, "tmp/tmp/0", NULL), NULL), NULL), NULL));
- /* Download something else 1 */
+ printf("==== Download something else 1 ====\n");
run_dl_https("https://a.b.c/e", 0, 1);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hunode("a.b.c/d",
- huftnode("a.b.c/d/e", HFULL, "tmp/tmp/0", NULL), NULL),
- huftnode("a.b.c/e", HFULL, "tmp/tmp/1", NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hunode(HO2UP("a.b.c/d"),
+ huftnode(HO2UP("a.b.c/d/e"), HFULL, "tmp/tmp/0", NULL), NULL),
+ huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/1", NULL), NULL), NULL));
- /* Download something else 2 */
+ printf("==== Download something else 2 ====\n");
run_dl_https("https://x.y.z/e", 0, 1);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hunode("a.b.c/d",
- huftnode("a.b.c/d/e", HFULL, "tmp/tmp/0", NULL), NULL),
- huftnode("a.b.c/e", HFULL, "tmp/tmp/1", NULL), NULL),
- hunode("x.y.z",
- huftnode("x.y.z/e", HFULL, "tmp/tmp/2", NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hunode(HO2UP("a.b.c/d"),
+ huftnode(HO2UP("a.b.c/d/e"), HFULL, "tmp/tmp/0", NULL), NULL),
+ huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/1", NULL), NULL),
+ hunode(HO2UP("x.y.z"),
+ huftnode(HO2UP("x.y.z/e"), HFULL, "tmp/tmp/2", NULL), NULL), NULL));
cleanup_test();
}
{
setup_test();
+ printf("==== Startup ====\n");
dl_error = 0;
run_dl_https("https://a.b.c/d", 0, 1);
dl_error = -EINVAL;
run_dl_https("https://a.b.c/e", -EINVAL, 1);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- huftnode("a.b.c/d", HFULL, "tmp/tmp/0", NULL),
- huftnode("a.b.c/e", HFAILED, NULL, NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL),
+ huftnode(HO2UP("a.b.c/e"), HFAILED, NULL, NULL), NULL), NULL));
- /* Regardless of error, not reattempted because same iteration */
+ printf("==== Regardless of error, not reattempted because same iteration ====\n");
dl_error = -EINVAL;
run_dl_https("https://a.b.c/d", 0, 0);
dl_error = 0;
run_dl_https("https://a.b.c/e", -EINVAL, 0);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- huftnode("a.b.c/d", HFULL, "tmp/tmp/0", NULL),
- huftnode("a.b.c/e", HFAILED, NULL, NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL),
+ huftnode(HO2UP("a.b.c/e"), HFAILED, NULL, NULL), NULL), NULL));
cleanup_test();
}
{
setup_test();
- /* First iteration; make a tree and clean it */
+ printf("==== First iteration; make a tree and clean it ====\n");
new_iteration(true);
run_dl_https("https://a.b.c/d", 0, 1);
run_dl_https("https://a.b.c/e", 0, 1);
run_cleanup();
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hufnode("a.b.c/d", HFULL, NULL),
- hufnode("a.b.c/e", HFULL, NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hufnode(HO2UP("a.b.c/d"), HFULL, NULL),
+ hufnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
- /* Remove one branch */
+ printf("==== Remove one branch ====\n");
new_iteration(true);
run_dl_https("https://a.b.c/d", 0, 1);
run_cleanup();
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hufnode("a.b.c/d", HFULL, NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hufnode(HO2UP("a.b.c/d"), HFULL, NULL), NULL), NULL));
- /* Change the one branch */
+ printf("==== Change the one branch ====\n");
new_iteration(true);
run_dl_https("https://a.b.c/e", 0, 1);
run_cleanup();
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hufnode("a.b.c/e", HFULL, NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hufnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
- /* Add a child to the same branch, do not update the old one */
+ printf("==== Add a child to the same branch, do not update the old one ====\n");
new_iteration(true);
run_dl_https("https://a.b.c/e/f/g", 0, 1);
run_cleanup();
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hunode("a.b.c/e",
- hunode("a.b.c/e/f",
- hufnode("a.b.c/e/f/g", HFULL, NULL), NULL), NULL), NULL), NULL));
-
- /*
- * Download parent, do not update child.
- * Children need to die, because parent is now a file.
- */
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hunode(HO2UP("a.b.c/e"),
+ hunode(HO2UP("a.b.c/e/f"),
+ hufnode(HO2UP("a.b.c/e/f/g"), HFULL, NULL), NULL), NULL), NULL), NULL));
+
+ printf("==== Download parent, do not update child ====\n");
+ /* (Children need to die, because parent is now a file) */
new_iteration(true);
run_dl_https("https://a.b.c/e/f", 0, 1);
run_cleanup();
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hunode("a.b.c/e",
- hufnode("a.b.c/e/f", HFULL, NULL), NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hunode(HO2UP("a.b.c/e"),
+ hufnode(HO2UP("a.b.c/e/f"), HFULL, NULL), NULL), NULL), NULL));
- /* Do it again. */
+ printf("==== Do it again ====\n");
new_iteration(true);
run_dl_https("https://a.b.c/e", 0, 1);
run_cleanup();
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hufnode("a.b.c/e", HFULL, NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hufnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
- /* Empty the tree */
+ printf("==== Empty the tree ====\n");
new_iteration(true);
run_cleanup();
- ck_cache_https(hunode("", NULL));
+ ck_cache_https(hunode(HE2UP, NULL));
- /* Node exists, but file doesn't */
+ printf("==== Node exists, but file doesn't ====\n");
new_iteration(true);
run_dl_https("https://a.b.c/e", 0, 1);
run_dl_https("https://a.b.c/f/g/h", 0, 1);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- huftnode("a.b.c/e", HFULL, "tmp/tmp/7", NULL),
- hunode("a.b.c/f",
- hunode("a.b.c/f/g",
- huftnode("a.b.c/f/g/h", HFULL, "tmp/tmp/8", NULL), NULL), NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/7", NULL),
+ hunode(HO2UP("a.b.c/f"),
+ hunode(HO2UP("a.b.c/f/g"),
+ huftnode(HO2UP("a.b.c/f/g/h"), HFULL, "tmp/tmp/8", NULL), NULL), NULL), NULL), NULL));
run_cleanup(); /* Move from tmp/tmp to tmp/https */
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hufnode("a.b.c/e", HFULL, NULL),
- hunode("a.b.c/f",
- hunode("a.b.c/f/g",
- hufnode("a.b.c/f/g/h", HFULL, NULL), NULL), NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hufnode(HO2UP("a.b.c/e"), HFULL, NULL),
+ hunode(HO2UP("a.b.c/f"),
+ hunode(HO2UP("a.b.c/f/g"),
+ hufnode(HO2UP("a.b.c/f/g/h"), HFULL, NULL), NULL), NULL), NULL), NULL));
ck_assert_int_eq(0, file_rm_rf("tmp/https/a.b.c/f/g/h"));
run_cleanup(); /* Actual test */
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hufnode("a.b.c/e", HFULL, NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hufnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
- /* Temporal version disappears before we get a commit */
+ printf("==== Temporal version disappears before we get a commit ====\n");
new_iteration(true);
run_dl_https("https://a.b.c/e", 0, 1);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- huftnode("a.b.c/e", HFULL, "tmp/tmp/9", NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/9", NULL), NULL), NULL));
ck_assert_int_eq(0, file_rm_rf("tmp/tmp/9"));
run_cleanup();
- ck_cache_https(hunode("", NULL));
+ ck_cache_https(hunode(HE2UP, NULL));
- /* Temporal version disappears after we get a commit */
+ printf("==== Temporal version disappears after we get a commit ====\n");
new_iteration(true);
run_dl_https("https://a.b.c/e", 0, 1);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- huftnode("a.b.c/e", HFULL, "tmp/tmp/A", NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/A", NULL), NULL), NULL));
run_cleanup(); /* Commit */
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hufnode("a.b.c/e", HFULL, NULL, NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hufnode(HO2UP("a.b.c/e"), HFULL, NULL, NULL), NULL), NULL));
new_iteration(false);
run_dl_https("https://a.b.c/e", 0, 1);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- huftnode("a.b.c/e", HFULL, "tmp/tmp/B", NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/B", NULL), NULL), NULL));
ck_assert_int_eq(0, file_rm_rf("tmp/tmp/B"));
run_cleanup();
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hufnode("a.b.c/e", HFULL, NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hufnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
cleanup_test();
}
{
setup_test();
- /* Set up */
+ printf("==== Set up ====\n");
dl_error = 0;
run_dl_https("https://a.b.c/d", 0, 1);
dl_error = -EINVAL;
run_dl_https("https://a.b.c/e", -EINVAL, 1);
PR_DEBUG;
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- huftnode("a.b.c/d", HFULL, "tmp/tmp/0", NULL),
- hufnode("a.b.c/e", HFAILED, NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL),
+ hufnode(HO2UP("a.b.c/e"), HFAILED, NULL), NULL), NULL));
- /* Deleted because file ENOENT. */
+ printf("==== Deleted because file ENOENT ====\n");
run_cleanup();
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hufnode("a.b.c/d", HFULL, NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hufnode(HO2UP("a.b.c/d"), HFULL, NULL), NULL), NULL));
- /* Fail d */
+ printf("==== Fail d ====\n");
new_iteration(false);
dl_error = -EINVAL;
run_dl_https("https://a.b.c/d", -EINVAL, 1);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hufnode("a.b.c/d", CNF_CACHED | CNF_FRESH, NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hufnode(HO2UP("a.b.c/d"), CNF_CACHED | CNF_FRESH, NULL), NULL), NULL));
- /* Not deleted, because not old */
+ printf("==== Not deleted, because not old ====\n");
new_iteration(false);
run_cleanup();
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- hufnode("a.b.c/d", CNF_CACHED, NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ hufnode(HO2UP("a.b.c/d"), CNF_CACHED, NULL), NULL), NULL));
- /* Become old */
+ printf("==== Become old ====\n");
new_iteration(true);
run_cleanup();
- ck_cache_https(hunode("", NULL));
+ ck_cache_https(hunode(HE2UP, NULL));
cleanup_test();
}
run_dl_https("https://a.b.c/d", 0, 1);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- huftnode("a.b.c/d", HFULL, "tmp/tmp/0", NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL), NULL), NULL));
run_dl_https("https://a.b.c/d/.", 0, 0);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- huftnode("a.b.c/d", HFULL, "tmp/tmp/0", NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL), NULL), NULL));
run_dl_https("https://a.b.c/d/e/..", 0, 0);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- huftnode("a.b.c/d", HFULL, "tmp/tmp/0", NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL), NULL), NULL));
run_dl_https("https://a.b.c/./d/../e", 0, 1);
ck_cache_https(
- hunode("",
- hunode("a.b.c",
- huftnode("a.b.c/d", HFULL, "tmp/tmp/0", NULL),
- huftnode("a.b.c/e", HFULL, "tmp/tmp/1", NULL), NULL), NULL));
+ hunode(HE2UP,
+ hunode(HO2UP("a.b.c"),
+ huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL),
+ huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/1", NULL), NULL), NULL));
cleanup_test();
}
int tests_failed;
suite = thread_pool_suite();
+ dls[0] = "Fort\n";
runner = srunner_create(suite);
srunner_run_all(runner, CK_NORMAL);
#include "cache_util.h"
+#include <check.h>
#include <string.h>
#include "types/uthash.h"
-static struct cache_node *
-node(char const *schema, char const *path, int flags, char const *tmpdir,
+static int
+cnf_clean(int flags)
+{
+ return flags & ~(CNF_FREE_URL | CNF_FREE_PATH | CNF_FREE_TMPPATH);
+}
+
+void
+ck_assert_cachent_eq(struct cache_node *expected, struct cache_node *actual)
+{
+ struct cache_node *echild, *achild, *tmp;
+
+ PR_DEBUG_MSG("Comparing %s vs %s", expected->url, actual->url);
+
+ ck_assert_str_eq(expected->url, actual->url);
+ ck_assert_str_eq(expected->path, actual->path);
+ ck_assert_str_eq(expected->name, actual->name);
+ ck_assert_int_eq(cnf_clean(expected->flags), cnf_clean(actual->flags));
+ if (expected->tmppath)
+ ck_assert_str_eq(expected->tmppath, actual->tmppath);
+ else
+ ck_assert_ptr_eq(NULL, actual->tmppath);
+
+ HASH_ITER(hh, expected->children, echild, tmp) {
+ HASH_FIND(hh, actual->children, echild->name,
+ strlen(echild->name), achild);
+ if (achild == NULL)
+ ck_abort_msg("Expected not found: %s", echild->url);
+ ck_assert_cachent_eq(echild, achild);
+ }
+
+ HASH_ITER(hh, actual->children, achild, tmp) {
+ HASH_FIND(hh, expected->children, achild->name,
+ strlen(achild->name), echild);
+ if (echild == NULL)
+ ck_abort_msg("Actual not found: %s", achild->url);
+ }
+}
+
+struct cache_node *
+vcreate_node(char const *url, char const *path, int flags, char const *tmppath,
va_list children)
{
struct cache_node *result;
struct cache_node *child;
char buffer[64];
- char const *slash;
result = pzalloc(sizeof(struct cache_node));
- ck_assert(snprintf(buffer, 64, "%s://%s", schema, path) < 64);
- result->url = pstrdup(buffer);
- slash = (path[0] == 0) ? "" : "/";
- ck_assert(snprintf(buffer, 64, "tmp/%s%s%s", schema, slash, path) < 64);
- result->path = pstrdup(buffer);
-
+ result->url = (char *)url;
+ result->path = (char *)path;
result->name = strrchr(result->path, '/') + 1;
ck_assert_ptr_ne(NULL, result->name);
result->flags = flags;
- result->tmppath = tmpdir ? pstrdup(tmpdir) : NULL;
+ result->tmppath = (char *)tmppath;
while ((child = va_arg(children, struct cache_node *)) != NULL) {
HASH_ADD_KEYPTR(hh, result->children, child->name,
}
struct cache_node *
-ruftnode(char const *path, int flags, char const *tmpdir, ...)
+ruftnode(char const *url, char const *path, int flags, char const *tmppath, ...)
{
struct cache_node *result;
va_list children;
- va_start(children, tmpdir);
- result = node("rsync", path, flags, tmpdir, children);
+ va_start(children, tmppath);
+ result = vcreate_node(url, path, flags, tmppath, children);
va_end(children);
return result;
}
struct cache_node *
-rufnode(char const *path, int flags, ...)
+rufnode(char const *url, char const *path, int flags, ...)
{
struct cache_node *result;
va_list children;
va_start(children, flags);
- result = node("rsync", path, flags, NULL, children);
+ result = vcreate_node(url, path, flags, NULL, children);
va_end(children);
return result;
}
struct cache_node *
-runode(char const *path, ...)
+runode(char const *url, char const *path, ...)
{
struct cache_node *result;
va_list children;
va_start(children, path);
- result = node("rsync", path, 0, NULL, children);
+ result = vcreate_node(url, path, 0, NULL, children);
va_end(children);
return result;
}
struct cache_node *
-huftnode(char const *path, int flags, char const *tmpdir, ...)
+huftnode(char const *url, char const *path, int flags, char const *tmppath, ...)
{
struct cache_node *result;
va_list children;
- va_start(children, tmpdir);
- result = node("https", path, flags, tmpdir, children);
+ va_start(children, tmppath);
+ result = vcreate_node(url, path, flags, tmppath, children);
va_end(children);
return result;
}
-struct cache_node *
-hufnode(char const *path, int flags, ...)
+struct cache_node *hufnode(char const *url, char const *path, int flags, ...)
{
struct cache_node *result;
va_list children;
va_start(children, flags);
- result = node("https", path, flags, NULL, children);
+ result = vcreate_node(url, path, flags, NULL, children);
va_end(children);
return result;
}
-struct cache_node *
-hunode(char const *path, ...)
+struct cache_node *hunode(char const *url, char const *path, ...)
{
struct cache_node *result;
va_list children;
va_start(children, path);
- result = node("https", path, 0, NULL, children);
+ result = vcreate_node(url, path, 0, NULL, children);
va_end(children);
return result;
#include <stdarg.h>
#include "cachent.h"
-struct cache_node *ruftnode(char const *, int , char const *, ...);
-struct cache_node *rufnode(char const *, int , ...);
-struct cache_node *runode(char const *, ...);
+void ck_assert_cachent_eq(struct cache_node *, struct cache_node *);
-struct cache_node *huftnode(char const *, int , char const *, ...);
-struct cache_node *hufnode(char const *, int , ...);
-struct cache_node *hunode(char const *, ...);
+struct cache_node *vcreate_node(char const *, char const *, int, char const *, va_list);
+
+// XXX Rename ?
+struct cache_node *ruftnode(char const *, char const *, int, char const *, ...);
+struct cache_node *rufnode(char const *, char const *, int, ...);
+struct cache_node *runode(char const *, char const *, ...);
+
+struct cache_node *huftnode(char const *, char const *, int, char const *, ...);
+struct cache_node *hufnode(char const *, char const *, int, ...);
+struct cache_node *hunode(char const *, char const *, ...);
+
+/* rsync offset to url + path */
+#define RO2UP(offset) "rsync://" offset, "tmp/rsync/" offset
+/* https offset to url + path */
+#define HO2UP(offset) "https://" offset, "tmp/https/" offset
+
+/* rsync empty to url + path */
+#define RE2UP "rsync://", "tmp/rsync"
+/* https empty to url + path */
+#define HE2UP "https://", "tmp/https"
#endif /* TEST_CACHE_UTIL_H_ */
{
struct cache_node *root, *a, *b;
- a = runode("a", NULL);
+ a = runode(RO2UP("a"), NULL);
dn = 0;
cachent_delete(a);
ck_assert_uint_eq(1, dn);
ck_assert_str_eq("a", deleted[0]);
- a = runode("a", NULL);
- root = runode("", a, NULL);
+ a = runode(RO2UP("a"), NULL);
+ root = runode(RE2UP, a, NULL);
dn = 0;
cachent_delete(a);
ck_assert_ptr_eq(NULL, root->children);
ck_assert_uint_eq(1, dn);
ck_assert_str_eq("rsync", deleted[0]);
- b = runode("a/b",
- runode("a/b/c", NULL),
- runode("a/b/d", NULL),
- runode("a/b/e", NULL),
- runode("a/b/f", NULL), NULL);
- a = runode("a",
+ b = runode(RO2UP("a/b"),
+ runode(RO2UP("a/b/c"), NULL),
+ runode(RO2UP("a/b/d"), NULL),
+ runode(RO2UP("a/b/e"), NULL),
+ runode(RO2UP("a/b/f"), NULL), NULL);
+ a = runode(RO2UP("a"),
b,
- runode("a/g",
- runode("a/g/h",
- runode("a/g/h/i", NULL), NULL),
- runode("a/g/j",
- runode("a/g/j/k", NULL), NULL),
- runode("a/g/l",
- runode("a/g/l/m", NULL), NULL),
- runode("a/g/n",
- runode("a/g/n/o", NULL), NULL), NULL), NULL);
- root = runode("", a, NULL);
+ runode(RO2UP("a/g"),
+ runode(RO2UP("a/g/h"),
+ runode(RO2UP("a/g/h/i"), NULL), NULL),
+ runode(RO2UP("a/g/j"),
+ runode(RO2UP("a/g/j/k"), NULL), NULL),
+ runode(RO2UP("a/g/l"),
+ runode(RO2UP("a/g/l/m"), NULL), NULL),
+ runode(RO2UP("a/g/n"),
+ runode(RO2UP("a/g/n/o"), NULL), NULL), NULL), NULL);
+ root = runode(RE2UP, a, NULL);
dn = 0;
cachent_delete(b);
root = NULL;
ck_traverse(root, NULL);
- root = runode("a", NULL);
+ root = runode(RO2UP("a"), NULL);
ck_traverse(root, "tmp/rsync/a", NULL);
- root = runode("a",
- runode("a/b", NULL), NULL);
+ root = runode(RO2UP("a"),
+ runode(RO2UP("a/b"), NULL), NULL);
ck_traverse(root, "tmp/rsync/a", "tmp/rsync/a/b", NULL);
- root = runode("a",
- runode("a/b",
- runode("a/b/c", NULL), NULL), NULL);
+ root = runode(RO2UP("a"),
+ runode(RO2UP("a/b"),
+ runode(RO2UP("a/b/c"), NULL), NULL), NULL);
ck_traverse(root,
"tmp/rsync/a",
"tmp/rsync/a/b",
"tmp/rsync/a/b/c", NULL);
- root = runode("a",
- runode("a/b",
- runode("a/b/c", NULL),
- runode("a/b/d", NULL), NULL), NULL);
+ root = runode(RO2UP("a"),
+ runode(RO2UP("a/b"),
+ runode(RO2UP("a/b/c"), NULL),
+ runode(RO2UP("a/b/d"), NULL), NULL), NULL);
ck_traverse(root,
"tmp/rsync/a",
"tmp/rsync/a/b",
"tmp/rsync/a/b/c",
"tmp/rsync/a/b/d", NULL);
- root = runode("a",
- runode("a/b",
- runode("a/b/c", NULL),
- runode("a/b/d", NULL), NULL),
- runode("a/e", NULL), NULL);
+ root = runode(RO2UP("a"),
+ runode(RO2UP("a/b"),
+ runode(RO2UP("a/b/c"), NULL),
+ runode(RO2UP("a/b/d"), NULL), NULL),
+ runode(RO2UP("a/e"), NULL), NULL);
ck_traverse(root,
"tmp/rsync/a",
"tmp/rsync/a/b",
"tmp/rsync/a/b/d",
"tmp/rsync/a/e", NULL);
- root = runode("a",
- runode("a/b", NULL),
- runode("a/c",
- runode("a/c/d", NULL),
- runode("a/c/e", NULL), NULL), NULL);
+ root = runode(RO2UP("a"),
+ runode(RO2UP("a/b"), NULL),
+ runode(RO2UP("a/c"),
+ runode(RO2UP("a/c/d"), NULL),
+ runode(RO2UP("a/c/e"), NULL), NULL), NULL);
ck_traverse(root,
"tmp/rsync/a",
"tmp/rsync/a/b",
"tmp/rsync/a/c/d",
"tmp/rsync/a/c/e", NULL);
- root = runode("a",
- runode("a/b",
- runode("a/b/c", NULL),
- runode("a/b/d", NULL), NULL),
- runode("a/e",
- runode("a/e/f", NULL),
- runode("a/e/g", NULL), NULL), NULL);
+ root = runode(RO2UP("a"),
+ runode(RO2UP("a/b"),
+ runode(RO2UP("a/b/c"), NULL),
+ runode(RO2UP("a/b/d"), NULL), NULL),
+ runode(RO2UP("a/e"),
+ runode(RO2UP("a/e/f"), NULL),
+ runode(RO2UP("a/e/g"), NULL), NULL), NULL);
ck_traverse(root,
"tmp/rsync/a",
"tmp/rsync/a/b",
"tmp/rsync/a/e/f",
"tmp/rsync/a/e/g", NULL);
- root = runode("a",
- runode("a/b",
- runode("a/b/c", NULL),
- runode("a/b/d", NULL),
- runode("a/b/e", NULL),
- runode("a/b/f", NULL), NULL),
- runode("a/g",
- runode("a/g/h",
- runode("a/g/h/i", NULL), NULL),
- runode("a/g/j",
- runode("a/g/j/k", NULL), NULL),
- runode("a/g/l",
- runode("a/g/l/m", NULL), NULL),
- runode("a/g/n",
- runode("a/g/n/o", NULL), NULL), NULL), NULL);
+ root = runode(RO2UP("a"),
+ runode(RO2UP("a/b"),
+ runode(RO2UP("a/b/c"), NULL),
+ runode(RO2UP("a/b/d"), NULL),
+ runode(RO2UP("a/b/e"), NULL),
+ runode(RO2UP("a/b/f"), NULL), NULL),
+ runode(RO2UP("a/g"),
+ runode(RO2UP("a/g/h"),
+ runode(RO2UP("a/g/h/i"), NULL), NULL),
+ runode(RO2UP("a/g/j"),
+ runode(RO2UP("a/g/j/k"), NULL), NULL),
+ runode(RO2UP("a/g/l"),
+ runode(RO2UP("a/g/l/m"), NULL), NULL),
+ runode(RO2UP("a/g/n"),
+ runode(RO2UP("a/g/n/o"), NULL), NULL), NULL), NULL);
ck_traverse(root,
"tmp/rsync/a",
"tmp/rsync/a/b",
{
struct cache_node *rsync, *abc, *d, *e, *f, *g, *h, *ee;
- rsync = cachent_create_root(false);
+ rsync = cachent_root_rsync();
ck_assert_ptr_ne(NULL, rsync);
ck_assert_ptr_eq(NULL, rsync->parent);
ck_assert_str_eq("rsync://", rsync->url);
#include "file.c"
#include "hash.c"
#include "mock.c"
-#include "types/map.c"
#include "types/path.c"
-MOCK_ABORT_INT(cache_tmpfile, char **filename)
-
/* Actually mostly tests libcrypto's sanity, not Fort's. */
START_TEST(test_hash)
{
MOCK_NULL(config_get_slurm, char const *, void)
MOCK(config_get_tal, char const *, "tal/", void)
MOCK(config_get_local_repository, char const *, "tmp", void)
+MOCK(cfg_cache_threshold, time_t, 60 * 60 * 24 * 7, void)
MOCK(config_get_mode, enum mode, STANDALONE, void)
+MOCK_UINT(config_get_rrdp_delta_threshold, 5, void)
MOCK_TRUE(config_get_rsync_enabled, void)
MOCK_UINT(config_get_rsync_priority, 50, void)
MOCK_TRUE(config_get_http_enabled, void)
--- /dev/null
+#include "http.h"
+
+#include <check.h>
+#include "file.h"
+
+static int dl_error;
+static char const *dls[8];
+static unsigned int https_counter; /* Times http_download() was called */
+
+int
+http_download(char const *url, char const *path, curl_off_t ims, bool *changed)
+{
+ char const *content;
+
+ if (dl_error) {
+ printf("Simulating failed HTTP download.\n");
+ https_counter++;
+ if (changed)
+ *changed = false;
+ return dl_error;
+ }
+
+ printf("Simulating HTTP download: %s -> %s\n", url, path);
+
+ content = dls[https_counter++];
+ if (!content)
+ ck_abort_msg("Test was not expecting an HTTP download.");
+
+ ck_assert_int_eq(0, file_write_full(path,
+ (unsigned char const *)content, strlen(content)));
+
+ if (changed)
+ *changed = true;
+ return 0;
+}
#include "alloc.c"
#include "base64.c"
#include "cachent.c"
+#include "cachetmp.c"
#include "common.c"
#include "file.c"
#include "hash.c"
/* Mocks */
-int
-cache_tmpfile(char **filename)
-{
- static unsigned int file_counter = 0;
- char *result;
- int written;
-
- result = pmalloc(10);
- written = snprintf(result, 10, "tmp/%u", file_counter++);
- ck_assert(4 < written && written < 10);
-
- *filename = result;
- return 0;
-}
-
MOCK_VOID(fnstack_push, char const *file)
MOCK_VOID(fnstack_pop, void)
MOCK_VOID(__delete_node_cb, struct cache_node const *node)
-MOCK_UINT(config_get_rrdp_delta_threshold, 5, void)
MOCK_ABORT_INT(http_download, char const *url, char const *path, curl_off_t ims,
bool *changed)
/* Mocks end */
static void
-ck_rrdp_session(char const *session, char const *serial, struct rrdp_session *actual)
+ck_rrdp_session(char const *session, char const *serial,
+ struct rrdp_session *actual)
{
BIGNUM *bn;
}
static void
-validate_cachefile_notif(struct cachefile_notification *notif, unsigned long __serial, ...)
+validate_cachefile_notif(struct cachefile_notification *notif,
+ unsigned long __serial, ...)
{
struct rrdp_serial serial;
va_list args;
}
END_TEST
-static void
-init_map(struct cache_node *map, char *url, char *path)
-{
- memset(map, 0, sizeof(*map));
-
- map->url = url;
- map->path = path;
- map->tmppath = path;
- map->name = strrchr(path, '/') + 1;
-}
-
START_TEST(test_parse_notification_ok)
{
- struct cache_node map;
struct update_notification notif;
ck_assert_int_eq(0, relax_ng_init());
- init_map(&map, "https://host/notification.xml", "resources/rrdp/notif-ok.xml");
- ck_assert_int_eq(0, parse_notification(&map, ¬if));
+ ck_assert_int_eq(0, parse_notification("https://host/notification.xml",
+ "resources/rrdp/notif-ok.xml", ¬if));
- ck_assert_str_eq("9df4b597-af9e-4dca-bdda-719cce2c4e28", (char const *)notif.session.session_id);
+ ck_assert_str_eq("9df4b597-af9e-4dca-bdda-719cce2c4e28",
+ (char const *)notif.session.session_id);
ck_assert_str_eq("3", (char const *)notif.session.serial.str);
ck_assert_str_eq("https://host/9d-8/3/snapshot.xml", notif.snapshot.uri);
ck_assert_uint_eq(2, notif.deltas.len);
ck_assert_str_eq("2", (char const *)notif.deltas.array[0].serial.str);
- ck_assert_str_eq("https://host/9d-8/2/delta.xml", notif.deltas.array[0].meta.uri);
+ ck_assert_str_eq("https://host/9d-8/2/delta.xml",
+ notif.deltas.array[0].meta.uri);
ck_assert_uint_eq(32, notif.deltas.array[0].meta.hash_len);
validate_01234_hash(notif.deltas.array[0].meta.hash);
ck_assert_str_eq("3", (char const *)notif.deltas.array[1].serial.str);
- ck_assert_str_eq("https://host/9d-8/3/delta.xml", notif.deltas.array[1].meta.uri);
+ ck_assert_str_eq("https://host/9d-8/3/delta.xml",
+ notif.deltas.array[1].meta.uri);
ck_assert_uint_eq(32, notif.deltas.array[1].meta.hash_len);
validate_01234_hash(notif.deltas.array[0].meta.hash);
START_TEST(test_parse_notification_0deltas)
{
- struct cache_node map;
struct update_notification notif;
ck_assert_int_eq(0, relax_ng_init());
- init_map(&map, "https://host/notification.xml", "resources/rrdp/notif-0deltas.xml");
- ck_assert_int_eq(0, parse_notification(&map, ¬if));
+ ck_assert_int_eq(0, parse_notification("https://host/notification.xml",
+ "resources/rrdp/notif-0deltas.xml", ¬if));
- ck_assert_str_eq("9df4b597-af9e-4dca-bdda-719cce2c4e28", (char const *)notif.session.session_id);
+ ck_assert_str_eq("9df4b597-af9e-4dca-bdda-719cce2c4e28",
+ (char const *)notif.session.session_id);
ck_assert_str_eq("3", (char const *)notif.session.serial.str);
ck_assert_str_eq("https://host/9d-8/3/snapshot.xml", notif.snapshot.uri);
struct update_notification notif;
ck_assert_int_eq(0, relax_ng_init());
- init_map(&map, "https://host/notification.xml", "resources/rrdp/notif-large-serial.xml");
- ck_assert_int_eq(0, parse_notification(&map, ¬if));
+ ck_assert_int_eq(0, parse_notification("https://host/notification.xml",
+ "resources/rrdp/notif-large-serial.xml", ¬if));
- ck_assert_str_eq("9df4b597-af9e-4dca-bdda-719cce2c4e28", (char const *)notif.session.session_id);
+ ck_assert_str_eq("9df4b597-af9e-4dca-bdda-719cce2c4e28",
+ (char const *)notif.session.session_id);
/*
* This seems to be the largest positive integer libxml2 supports,
* at least by default. It's significantly larger than 2^64.
* It's not as many digits as I was expecting though.
* Maybe research if it's possible to increase it further.
*/
- ck_assert_str_eq("999999999999999999999999", (char const *)notif.session.serial.str);
+ ck_assert_str_eq("999999999999999999999999",
+ (char const *)notif.session.serial.str);
ck_assert_str_eq("https://host/9d-8/3/snapshot.xml", notif.snapshot.uri);
ck_assert_uint_eq(32, notif.snapshot.hash_len);
static void
test_parse_notification_error(char *file)
{
- struct cache_node map;
struct update_notification notif;
ck_assert_int_eq(0, relax_ng_init());
- init_map(&map, "https://host/notification.xml", file);
- ck_assert_int_eq(-EINVAL, parse_notification(&map, ¬if));
+ ck_assert_int_eq(-EINVAL,
+ parse_notification("https://host/notification.xml", file, ¬if));
relax_ng_cleanup();
}
#include "alloc.c"
#include "base64.c"
#include "cachent.c"
+#include "cachetmp.c"
+#include "cache_util.c"
#include "common.c"
+#include "file.c"
+#include "hash.c"
#include "json_util.c"
#include "mock.c"
+#include "mock_https.c"
+#include "relax_ng.c"
#include "rrdp.c"
#include "types/path.c"
#include "types/url.c"
MOCK_VOID(fnstack_push, char const *file)
MOCK_VOID(fnstack_pop, void)
-MOCK_UINT(config_get_rrdp_delta_threshold, 5, void)
MOCK_VOID(__delete_node_cb, struct cache_node const *node)
-MOCK(hash_get_sha256, struct hash_algorithm const *, NULL, void)
-MOCK_INT(hash_validate_file, 0, struct hash_algorithm const *algorithm,
- char const *path, unsigned char const *expected, size_t expected_len)
-MOCK_INT(file_write_full, 0, char const *path, unsigned char *content,
- size_t content_len)
-
-int
-cache_tmpfile(char **filename)
+
+/* Utils */
+
+static void
+setup_test(void)
{
- *filename = pstrdup("tmp/a");
- return 0;
+ ck_assert_int_eq(0, system("rm -rf tmp/"));
+ ck_assert_int_eq(0, system("mkdir -p tmp/rsync tmp/https tmp/tmp"));
+ ck_assert_int_eq(0, hash_setup());
+ ck_assert_int_eq(0, relax_ng_init());
}
-int
-http_download(char const *url, char const *path, curl_off_t ims, bool *changed)
+static void
+cleanup_test(void)
{
- printf("http_download(): %s -> %s\n", url, path);
- if (changed)
- *changed = true;
- return 0;
+// ck_assert_int_eq(0, system("rm -rf tmp/"));
+ hash_teardown();
+ relax_ng_cleanup();
}
-static char const *dls[8];
-static unsigned int d;
-
-int
-relax_ng_parse(const char *path, xml_read_cb cb, void *arg)
+static void
+ck_file(char const *path)
{
- xmlTextReaderPtr reader;
- int read;
-
- /* TODO (warning) "XML_CHAR_ENCODING_NONE" */
- reader = xmlReaderForMemory(dls[d], strlen(dls[d]), path, "UTF-8", 0);
- if (reader == NULL)
- return pr_val_err("Unable to open %s (Cause unavailable).", path);
- d++;
-
- while ((read = xmlTextReaderRead(reader)) == 1) {
-// ck_assert_int_eq(1, xmlTextReaderIsValid(reader));
- ck_assert_int_eq(0, cb(reader, arg));
- }
-
- ck_assert_int_eq(read, 0);
-// ck_assert_int_eq(1, xmlTextReaderIsValid(reader));
-
- xmlFreeTextReader(reader);
- return 0;
+ FILE *file;
+ char buffer[8] = { 0 };
+
+ file = fopen(path, "rb");
+ ck_assert_ptr_ne(NULL, file);
+ ck_assert_int_eq(5, fread(buffer, 1, 8, file));
+ ck_assert_int_ne(0, feof(file));
+ ck_assert_int_eq(0, fclose(file));
+ ck_assert_str_eq("Fort\n", buffer);
}
-/* Tests */
-
#define NHDR(serial) "<notification " \
"xmlns=\"http://www.ripe.net/rpki/rrdp\" " \
"version=\"1\" " \
#define PBLSH(u, c) "<publish uri=\"" u "\">" c "</publish>"
+/* Tests */
+
START_TEST(startup)
{
+#define NOTIF_PATH "tmp/https/host/notification.xml"
struct cache_node notif;
+ setup_test();
+
memset(¬if, 0, sizeof(notif));
notif.url = "https://host/notification.xml";
- notif.path = "tmp/https/host/notification.xml";
+ notif.path = NOTIF_PATH;
notif.name = "notification.xml";
dls[0] = NHDR("3")
- NSS("https://host/9d-8/3/snapshot.xml", "0123456789abcdefABCDEF0123456789abcdefABCDEF0123456789abcdefABCD")
+ NSS("https://host/9d-8/3/snapshot.xml", "0c84fb949e7b5379ae091b86c41bb1a33cb91636b154b86ad1b1dedd44651a25")
NTAIL;
- dls[1] = SHDR("3") PBLSH("rsync://a/b/c.cer", "Rm9ydA==") STAIL;
+ dls[1] = SHDR("3") PBLSH("rsync://a/b/c.cer", "Rm9ydAo=") STAIL;
dls[2] = NULL;
- d = 0;
+ https_counter = 0;
ck_assert_int_eq(0, rrdp_update(¬if));
+ ck_assert_uint_eq(2, https_counter);
+ ck_file("tmp/tmp/0/a/b/c.cer");
+ ck_assert_cachent_eq(
+ ruftnode("rsync://", NOTIF_PATH, 0, "tmp/tmp/0",
+ ruftnode("rsync://a", NOTIF_PATH "/a", 0, "tmp/tmp/0/a",
+ ruftnode("rsync://a/b", NOTIF_PATH "/a/b", 0, "tmp/tmp/0/a/b",
+ ruftnode("rsync://a/b/c.cer", NOTIF_PATH "/a/b/c.cer", 0, "tmp/tmp/0/a/b/c.cer", NULL),
+ NULL),
+ NULL),
+ NULL),
+ notif.rrdp.subtree
+ );
+
+ dls[1] = NULL;
+ https_counter = 0;
+ ck_assert_int_eq(0, rrdp_update(¬if));
+ ck_assert_uint_eq(1, https_counter);
+ ck_file("tmp/tmp/0/a/b/c.cer");
+ ck_assert_cachent_eq(
+ ruftnode("rsync://", NOTIF_PATH, 0, "tmp/tmp/0",
+ ruftnode("rsync://a", NOTIF_PATH "/a", 0, "tmp/tmp/0/a",
+ ruftnode("rsync://a/b", NOTIF_PATH "/a/b", 0, "tmp/tmp/0/a/b",
+ ruftnode("rsync://a/b/c.cer", NOTIF_PATH "/a/b/c.cer", 0, "tmp/tmp/0/a/b/c.cer", NULL),
+ NULL),
+ NULL),
+ NULL),
+ notif.rrdp.subtree
+ );
+
+ cleanup_test();
}
END_TEST
#define TOTAL_CREATED 15
static struct deltas *created[TOTAL_CREATED];
-unsigned int
-config_get_deltas_lifetime(void)
-{
- return 5;
-}
+MOCK_UINT(config_get_deltas_lifetime, 5, void)
static int
foreach_cb(struct deltas *deltas, void *arg)