]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Wednesday
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Wed, 31 Jul 2024 19:48:01 +0000 (13:48 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Thu, 1 Aug 2024 18:20:47 +0000 (12:20 -0600)
26 files changed:
src/Makefile.am
src/cache.c
src/cache.h
src/cachent.c
src/cachent.h
src/cachetmp [new file with mode: 0644]
src/cachetmp.c [new file with mode: 0644]
src/cachetmp.h [new file with mode: 0644]
src/file.c
src/file.h
src/hash.c
src/relax_ng.c
src/relax_ng.h
src/rrdp.c
src/rrdp.h
src/types/map.c
test/cache_test.c
test/cache_util.c
test/cache_util.h
test/cachent_test.c
test/hash_test.c
test/mock.c
test/mock_https.c [new file with mode: 0644]
test/rrdp_test.c
test/rrdp_update_test.c
test/rtr/db/deltas_array_test.c

index 56f16aee3e400ac3351ea1b48fd954ae3cc2b228..62f74736919ebc0b422ad4876b0b6214a8efc565 100644 (file)
@@ -11,6 +11,7 @@ fort_SOURCES += asn1/signed_data.h asn1/signed_data.c
 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
index ac7fb75d6fd6536bc080a4dd6ad14110d3b4aeb2..d955b53c007bb9d679549c9b8b2963d7359d5747 100644 (file)
@@ -7,10 +7,10 @@
 #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"
@@ -46,13 +46,10 @@ static struct rpki_cache {
 //     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"
@@ -180,7 +177,7 @@ init_tmp_dir(void)
        char *dirname;
        int error;
 
-       dirname = get_cache_filename(TMPDIR, true);
+       dirname = get_cache_filename(CACHE_TMPDIR, true);
 
        error = mkdir(dirname, true);
        if (error != EEXIST)
@@ -211,37 +208,6 @@ cache_teardown(void)
        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)
 //{
@@ -337,8 +303,8 @@ cache_tmpfile(char **filename)
 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;
@@ -562,6 +528,7 @@ static int
 dl_http(struct cache_node *node)
 {
        char *tmppath;
+       time_t mtim;
        bool changed;
        int error;
 
@@ -574,17 +541,17 @@ dl_http(struct cache_node *node)
        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;
 }
@@ -826,7 +793,7 @@ rmf(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
 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));
index e5378e07172b643de2aee75965adea925f76525c..213fa8bbebafd9eb363490e3f42364f0ef4f5b4f 100644 (file)
@@ -7,8 +7,6 @@
 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() */
index e7f4da0352470cc6f3312c13b765f4394e4775b2..44b252e40e2ee5c28d51085d761c675c9631cc36 100644 (file)
@@ -7,20 +7,32 @@
 #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 *))
@@ -129,10 +141,13 @@ provide(struct cache_node *parent, char const *url,
        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);
 
@@ -196,9 +211,12 @@ __delete_node(struct cache_node *node)
 
        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;
@@ -246,7 +264,6 @@ print_node(struct cache_node *node, unsigned int tabs)
        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 " : "");
index e70114e44132bea789467f527ea2e42600322170..97143c9deac66ffcd0768954629146c029b9776b 100644 (file)
  * "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.)
@@ -67,7 +66,7 @@ struct cache_node {
        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 */
@@ -75,7 +74,8 @@ struct cache_node {
        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 *));
 
diff --git a/src/cachetmp b/src/cachetmp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/cachetmp.c b/src/cachetmp.c
new file mode 100644 (file)
index 0000000..60ff618
--- /dev/null
@@ -0,0 +1,37 @@
+#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;
+}
diff --git a/src/cachetmp.h b/src/cachetmp.h
new file mode 100644 (file)
index 0000000..dec35d1
--- /dev/null
@@ -0,0 +1,8 @@
+#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_ */
index 3d37337a1eed2995082b1cfa709396a1d3c1ba3c..184f8d36a8b5bd49a55e73698b1435ac73ca94bc 100644 (file)
@@ -62,7 +62,8 @@ file_write(char const *file_name, char const *mode, FILE **result)
 }
 
 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;
index 64e36cea06fcff17c2b082dcba975b8d426b1192..8e76f7d0d19d583b3b817a437c33bd1261df75cb 100644 (file)
@@ -25,7 +25,7 @@ struct file_contents {
 
 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);
index 1155fb32904e7255375e08d84e65eaf4abb43e0a..ec78b65355e1806bddc3ee183c7e1210c7bc811a 100644 (file)
@@ -163,6 +163,8 @@ hash_validate_file(struct hash_algorithm const *algorithm, char const *path,
        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;
index e3d909e616f170ea36512bd60d25132e13efd5a2..4ae956bbb795457855d8a1d03694e1a102468d55 100644 (file)
@@ -56,7 +56,7 @@ relax_ng_init(void)
 
        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;
index 4a3f780a91fa0bbadb538c8975936915410b210b..eeb22f704c7b56c46b4ef9f70ac45a12643f07e6 100644 (file)
 "  </define>"                                                          \
 "</grammar>"
 
-#define RRDP_V1_RNG_SIZE strlen(RRDP_V1_RNG)
-
 
 int relax_ng_init(void);
 void relax_ng_cleanup(void);
index 0332d05f56a5a09d112dfbca5898e650af8f50de..94f239d3298753a30a0f89e84625a604a392bd72 100644 (file)
@@ -71,7 +71,7 @@ struct withdraw {
 
 struct parser_args {
        struct rrdp_session *session;
-       struct cache_node *rpp;
+       struct cache_node *notif;
 };
 
 static BIGNUM *
@@ -479,21 +479,31 @@ delete_file(char const *path)
 }
 
 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;
        }
 
@@ -517,6 +527,7 @@ handle_publish(xmlTextReaderPtr reader, struct cache_node *rpp)
                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);
@@ -525,7 +536,7 @@ 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;
@@ -535,11 +546,13 @@ handle_withdraw(xmlTextReaderPtr reader, struct cache_node *rpp)
        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;
        }
 
@@ -738,13 +751,14 @@ xml_read_notif(xmlTextReaderPtr reader, void *arg)
 }
 
 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);
 
@@ -764,7 +778,7 @@ xml_read_snapshot(xmlTextReaderPtr reader, void *arg)
        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
@@ -781,9 +795,9 @@ xml_read_snapshot(xmlTextReaderPtr reader, void *arg)
 
 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);
 }
 
@@ -840,21 +854,21 @@ dl_tmp(char const *url, char **path)
 }
 
 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(&notif->snapshot, tmppath);
+       error = validate_hash(&new->snapshot, tmppath);
        if (error)
                goto end2;
-       error = parse_snapshot(&notif->session, tmppath, rpp);
+       error = parse_snapshot(&new->session, tmppath, notif);
        delete_file(tmppath);
 
 end2:  free(tmppath);
@@ -875,9 +889,9 @@ xml_read_delta(xmlTextReaderPtr reader, void *arg)
        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
@@ -894,7 +908,7 @@ xml_read_delta(xmlTextReaderPtr reader, void *arg)
 
 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;
@@ -907,14 +921,14 @@ parse_delta(struct update_notification *notif, struct notification_delta *delta,
        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;
@@ -925,7 +939,7 @@ handle_delta(struct update_notification *notif,
        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);
@@ -934,7 +948,7 @@ end:        fnstack_pop();
 }
 
 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;
@@ -948,7 +962,7 @@ handle_deltas(struct update_notification *notif, struct cache_node *node)
                return -ENOENT;
        }
 
-       old = &node->notif.session.serial;
+       old = &notif_node->rrdp.session.serial;
        new = &notif->session.serial;
 
        pr_val_debug("Handling RRDP delta serials %s-%s.", old->str, new->str);
@@ -971,7 +985,7 @@ handle_deltas(struct update_notification *notif, struct cache_node *node)
                    old->str, new->str);
 
        for (d = notif->deltas.len - diff; d < notif->deltas.len; d++) {
-               error = handle_delta(notif, &notif->deltas.array[d], node);
+               error = handle_delta(notif, &notif->deltas.array[d], notif_node);
                if (error)
                        return error;
        }
@@ -1072,39 +1086,59 @@ update_notif(struct cachefile_notification *old, struct update_notification *new
        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)
@@ -1112,62 +1146,39 @@ 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(&notif->notif, &new);
+               init_notif(&notif->rrdp, &new);
                goto end;
        }
 
-       old = &notif->notif;
+       old = &notif->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
@@ -1190,8 +1201,8 @@ rrdp_update(struct cache_node *notif)
 
 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:
@@ -1202,9 +1213,8 @@ reset_notif:
 clean_notif:
        update_notification_cleanup(&new);
 
-end:
-       fnstack_pop();
-       return error;
+end:   fnstack_pop();
+       return notif->dlerr;
 }
 
 #define TAGNAME_SESSION "session_id"
index e5ab53800291e1a293b333a1cb0e57209780c2df..d88a5b0aea7677a754f3f8689966b0301c4cdd98 100644 (file)
@@ -31,6 +31,7 @@ struct rrdp_hash {
  */
 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.
index 6b11c541a66d12d408444fb6a752dab28411468c..87ab958cc64c8a2fde42635cbc7fa0ccf5dec2da 100644 (file)
@@ -3,7 +3,7 @@
 #include <errno.h>
 
 #include "alloc.h"
-#include "cache.h"
+#include "cachetmp.h"
 #include "common.h"
 #include "config.h"
 #include "config/filename_format.h"
index 04db54fb18c545741cec53eb6beedb017380a300..dcedef532ebfe9bc34f83b632cd5c56569b05d51 100644 (file)
@@ -7,9 +7,11 @@
 #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"
@@ -17,8 +19,6 @@
 /* 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)
@@ -38,32 +38,10 @@ 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 */
@@ -74,8 +52,7 @@ setup_test(void)
        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
@@ -172,38 +149,6 @@ ck_path(struct cache_node *node)
        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)
 {
@@ -236,13 +181,13 @@ 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
@@ -274,7 +219,7 @@ static bool
 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;
 }
@@ -310,14 +255,6 @@ new_iteration(bool outdate)
        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)
 {
@@ -343,17 +280,16 @@ START_TEST(test_cache_download_rsync)
        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
@@ -362,10 +298,10 @@ START_TEST(test_cache_download_rsync)
        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
@@ -376,29 +312,28 @@ START_TEST(test_cache_download_rsync)
        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();
 }
@@ -408,32 +343,33 @@ START_TEST(test_cache_download_rsync_error)
 {
        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();
 }
@@ -443,34 +379,28 @@ START_TEST(test_cache_cleanup_rsync)
 {
        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);
@@ -478,92 +408,85 @@ START_TEST(test_cache_cleanup_rsync)
        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();
 }
@@ -573,45 +496,38 @@ START_TEST(test_cache_cleanup_rsync_error)
 {
        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();
 }
@@ -619,7 +535,7 @@ END_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;
@@ -628,33 +544,33 @@ START_TEST(test_cache_download_https)
 {
        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();
 }
@@ -664,26 +580,27 @@ START_TEST(test_cache_download_https_error)
 {
        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();
 }
@@ -695,135 +612,133 @@ START_TEST(test_cache_cleanup_https)
 {
        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();
 }
@@ -833,46 +748,46 @@ START_TEST(test_cache_cleanup_https_error)
 {
        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();
 }
@@ -884,28 +799,28 @@ START_TEST(test_dots)
 
        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();
 }
@@ -1144,6 +1059,7 @@ int main(void)
        int tests_failed;
 
        suite = thread_pool_suite();
+       dls[0] = "Fort\n";
 
        runner = srunner_create(suite);
        srunner_run_all(runner, CK_NORMAL);
index 85a121ff5631c26d86e46bc5d9f7a9d640e70ac0..74475bf58fb317d4c3be330ce971b0cc4a97e24a 100644 (file)
@@ -1,29 +1,63 @@
 #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,
@@ -35,78 +69,76 @@ node(char const *schema, char const *path, int flags, char const *tmpdir,
 }
 
 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;
index 2b3f1949cfcdc98ba2107d8fd07fbf35ce87d4ca..185895adbf62defe9e7ad74e80d47a557bacb251 100644 (file)
@@ -4,12 +4,27 @@
 #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_ */
index e3e1c070ccb850b5ed22b2c76bccef92040549f2..8ffe46ad4aea8179dee8d87d108cbc215df1cd90 100644 (file)
@@ -20,14 +20,14 @@ START_TEST(test_delete)
 {
        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);
@@ -39,23 +39,23 @@ START_TEST(test_delete)
        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);
@@ -124,36 +124,36 @@ START_TEST(test_traverse)
        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",
@@ -161,11 +161,11 @@ START_TEST(test_traverse)
                "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",
@@ -173,13 +173,13 @@ START_TEST(test_traverse)
                "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",
@@ -189,21 +189,21 @@ START_TEST(test_traverse)
                "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",
@@ -227,7 +227,7 @@ START_TEST(test_provide)
 {
        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);
index ffeee35fe34ee70f69b9d73e646524347cd8a0b5..eb1a3b5b714ff6745050784c3f4cfe83d7d792dc 100644 (file)
@@ -6,11 +6,8 @@
 #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)
 {
index 40bd6803f3a5a85c7e45be58c45e34d23c3670a9..7df1a8e4cb1e79b5889943e40a635b75fa0cc735 100644 (file)
@@ -113,7 +113,9 @@ v6addr2str2(struct in6_addr const *addr)
 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)
diff --git a/test/mock_https.c b/test/mock_https.c
new file mode 100644 (file)
index 0000000..c7fefbd
--- /dev/null
@@ -0,0 +1,35 @@
+#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;
+}
index 28e0d2325bfa10913f7f01c96adfff95e04b527f..20c379effb3f66b6a2a2cdeeedadf202542498d3 100644 (file)
@@ -5,6 +5,7 @@
 #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;
 
@@ -398,7 +384,8 @@ init_regular_notif(struct update_notification *notif, unsigned long serial, ...)
 }
 
 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;
@@ -465,27 +452,16 @@ START_TEST(test_update_notif)
 }
 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, &notif));
+       ck_assert_int_eq(0, parse_notification("https://host/notification.xml",
+           "resources/rrdp/notif-ok.xml", &notif));
 
-       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);
@@ -495,12 +471,14 @@ START_TEST(test_parse_notification_ok)
        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);
 
@@ -511,14 +489,14 @@ END_TEST
 
 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, &notif));
+       ck_assert_int_eq(0, parse_notification("https://host/notification.xml",
+           "resources/rrdp/notif-0deltas.xml", &notif));
 
-       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);
@@ -538,17 +516,19 @@ START_TEST(test_parse_notification_large_serial)
        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, &notif));
+       ck_assert_int_eq(0, parse_notification("https://host/notification.xml",
+           "resources/rrdp/notif-large-serial.xml", &notif));
 
-       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);
@@ -564,12 +544,11 @@ END_TEST
 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, &notif));
+       ck_assert_int_eq(-EINVAL,
+           parse_notification("https://host/notification.xml", file, &notif));
 
        relax_ng_cleanup();
 }
index 2896e42eca00bf0f376ab26fc0f8948f915dbf7b..303fc904d0cdc1416909c3c744dac756e5ed5efe 100644 (file)
@@ -3,9 +3,15 @@
 #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\" "                                        \
@@ -84,23 +72,58 @@ relax_ng_parse(const char *path, xml_read_cb cb, void *arg)
 
 #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(&notif, 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(&notif));
+       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(&notif));
+       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
 
index b48d6fd07089286936cdae6785aef1f8dc6cfb53..4676ea8f44e3322b1d458198ec2f1353ef67b317 100644 (file)
 #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)